
When we need?
For some reasons, you may want to have the generated HTML string from your React component instead of a mounted component and render it on the page. The typical case is for displaying rich text which is generated by Editor. However, ReactJS does this on purpose. It prevents XSS (cross-site scripting). To resolve above situation, ReactJS designers named the method that allows you to parse a string to HTML as dangerouslySetInnerHTML.
Why it’s dangerous?
As with the underlying DOM innerHTML property, you must exercise extreme caution! Unless the markup is coming from a completely trusted source, it is trivial to introduce an XSS vulnerability this way.
For example, if you use a Markdown library that converts Markdown to HTML, you trust that its parser doesn’t contain bugs, and the user only sees their own input, you can display the resulting HTML. Or even if your source contains some scripts, it will be executed during rendering and cause XSS issue.
Therefore, we always sanitize HTML string before using it to display. There are several libraries that can archieve it, for example:
They are well suited for cleaning up HTML fragments such as those created by CKEditor and other rich text editors. It is especially handy for removing unwanted CSS when copying and pasting from Word. Especially, preventing XSS attacks.
How to use React’s dangerouslySetInnerHTML?
Here is how to use it.
import { useEffect, useState } from "react";
import sanitizeHtml from "sanitize-html";
export const StringToHtml = () => {
const [html, setHtml] = useState<string>("");
useEffect(() => {
const rawHTML = "<div >Html stored as a string</div>";
// SECURITY HOLE: passing untrusted input to dangerouslySetInnerHTML. So, sanitize HTML before using.
setHtml(sanitizeHtml(rawHTML));
}, [html]);
return(
<div dangerouslySetInnerHTML={{__html: html}}></div>
)
}
How to render an HTML String for SSR purposes?
The ReactDOMServer module is a part of the official React library. It provides methods for rendering React components to static HTML. It’s useful for server-side rendering, where you want to generate HTML on the server and send it to the client.
import React from "react";
import ReactDOMServer from "react-dom/server";
const reactString = "<div>Hello, world!</div>";
const htmlString = ReactDOMServer.renderToString(React.createElement("div", { dangerouslySetInnerHTML: { __html: reactString } }));
console.log(htmlString);
// Output: <div>Hello, world!</div>
Same with client rendering, we also should sanitize HTML string before that.
You may consider using a framework like Next.js instead of manually rendering a React string to HTML. Using a framework like Next.js can offer a wide range of features and tools for building server-rendered applications.
References
https://www.learnbestcoding.com/post/84/string-to-html-in-react-js
https://react.dev/reference/react-dom/components/common#dangerously-setting-the-inner-html
https://www.emmanuelgautier.com/blog/react-element-render-to-string