Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace <a> with React <Link> in text

in my React app I am getting some HTML from another server (Wikipedia) and - in this text - want to replace all the links with react-router links.

What I have come up with is the following code:

// Parse HTML with JavaScript DOM Parser
let parser = new DOMParser();
let el = parser.parseFromString('<div>' + html + '</div>', 'text/html');

// Replace links with react-router links
el.querySelectorAll('a').forEach(a => {
  let to = a.getAttribute('href');
  let text = a.innerText;
  let link = <Link to={to}>{text}</Link>;
  a.replaceWith(link);
});
this.setState({
  html: el.innerHTML
})

Then later in render() I then inserted it into the page using

<div dangerouslySetInnerHTML={{__html: this.state.html}} />

The problem is that React JSX is not a native JavaScript element thus not working with replaceWith. I also assume that such a Link object can not be stored as text and then later be restored using dangerouslySetInnerHTML.

So: what is the best way to do this method? I want to keep all the various elements around the link so I cannot simply loop through the links in render()

like image 350
Jack Dunsk Avatar asked Apr 16 '26 02:04

Jack Dunsk


2 Answers

Umm, you really need to use Link Option 1:

import { renderToString } from 'react-dom/server';
el.querySelectorAll('a').forEach(a => {
  let to = a.getAttribute('href');
  let text = a.innerText;
  const link = renderToString(<Link to={to}>{text}</Link>);
  a.replaceWith(link);
});

Option 2: Use html-react-parser

like image 182
Subhendu Kundu Avatar answered Apr 18 '26 15:04

Subhendu Kundu


You can not render <Link> like this. Instead you could try another way:

el.querySelectorAll('a').forEach((a) => {
    a.addEventListener('click', (event) => {
       event.preventDefault()
       const href = a.getAttribute('href');
       // use React Router to link manually to href
    })
})

when click on <a> you routing manually.

See Programmatically navigate using react router

like image 29
chrisheyn Avatar answered Apr 18 '26 17:04

chrisheyn