Reputation: 6257
I have a html string that contains a link. I need to add the attribute rel="noopener"
for security purposes. The html string is injected through dangerouslySetInnerHtml:
const Component = ({ message }) => {
return (
<div>
<div dangerouslySetInnerHTML={{ __html: message }} />
<div>
);
};
The string looks like: Hello check out <a href="https://my-link.com" target="_blank">this page</a>
So the desired output would be: Hello check out <a href="https://my-link.com" target="_blank" rel="noopener">this page</a>
How to do it?
Upvotes: 0
Views: 439
Reputation: 76
Maybe consider using a function or component that puts it all together based on the data you send in? E.g.
function App() {
const linkBuilder = (textBefore, linkText, textAfter, href) => {
return (
<div>
{textBefore}
<a href={href} target="_blank">
{linkText}
</a>
{textAfter}
</div>
);
};
return (
<div>
{linkBuilder("Hello check out ", "this page", "", "www.google.com")}
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Also according to this you don't need rel=noopener
anymore if you use target="_blank"
. But if it's necessary you can pass it in as a boolean and apply it on the function/component side.
Upvotes: 0
Reputation: 385
Try this:
const Component = ({ message }) => {
function secureATags(html) {
// Parse HTML
let doc = (new DOMParser()).parseFromString(html, "text/html")
// Append attribute
doc.querySelectorAll('a').forEach(entry => {
entry.setAttribute('rel', 'noopener')
})
// Reserialize to HTML
return doc.body.innerHTML
}
return (
<div>
<div dangerouslySetInnerHTML={{ __html: secureATags(message) }} />
<div>
)
}
Upvotes: 2
Reputation: 798
Direct use of setDangerousInnerHtml
is strictly not recommended due to security issues.
you can use a plugin on npmjs.org
pkgname: React-html-parser for injecting the html safely
Upvotes: 0
Reputation: 24136
I would use the Browser DOM to achieve this, as follows:
const div = document.createElement("div");
div.innerHTML = 'Hello check out <a href="https://my-link.com" target="_blank">this page</a>';
div.childNodes[1].setAttribute("rel", "noopener");
console.log(div.innerHTML);
If the actual HTML text is more complex than in your example, then div.childNodes[1]
will need to be replaced with code that looks for and selects the proper node. But even then (or especially then?), this is probably the easiest and most reliable way to achieve your goal.
Upvotes: 0