Complete guide on React dangerouslySetInnerHTML

Have you ever noticed that if you have a string with HTML and you try to print it on the screen, it doesn’t quite turn out the way you planned it?


const htmlString = `<h1>I'm a string with HTML!</h1>`;

const App = () => <div>{htmlString}</div>;
React HTML string output

Odd.

This happens because React JSX is sanitizing the output to prevent any cross-site scripting (XSS).

To make this work, you’re going to have to use React dangerouslySetInnerHTML.

Let’s dive into when to use this property, and how to use it to your advantage.

When do you use React dangerouslySetInnerHTML?

99% of the time, the only time you’re going to use React dangerouslySetInnerHTML is when an API response returns HTML.

For example, the WordPress REST api returns HTML in one of its response properties called content.

If you’re curious to see a sample of a WordPress response object, take a look at this article, “How to make WordPress headless and fetch posts with JavaScript“.

In the context of any CMS using a wysiwyg editor, you want that data of what text is part of a header and what text is part of paragraph. So this is a great use case of when to use React dangerouslySetInnerHTML.

How to use dangerouslySetInnerHTML in React

Let’s take the first code example above, and try to make the HTML string render properly by using dangerouslySetInnerHTML in React


const htmlString = `<h1>I'm a string with HTML!</h1>`;

const App = () => <div dangerouslySetInnerHTML={{ __html: htmlString }} />;

Every HTML element has the React the dangerouslySetInnerHTML property.

dangerouslySetInnerHTML must equal an object. And in that object, a property called __html must equal the string of HTML.

That’s it!

Can you use React dangerouslySetInnerHTML without the wrapper div?

Yes.

You can use dangerouslySetInnerHTML in all HTML elements.

Here are some examples on how to use it with other HTML elements.


const htmlString = `<h1>I'm a string with HTML!</h1>`;

// Div element
<div dangerouslySetInnerHTML={{ __html: htmlString, }} />

// Span element
<span dangerouslySetInnerHTML={{ __html: htmlString, }} />

// Article element
<article dangerouslySetInnerHTML={{ __html: htmlString, }} />

// H1 element
<h1 dangerouslySetInnerHTML={{ __html: htmlString, }} />

// Head element
<head dangerouslySetInnerHTML={{ __html: htmlString, }} />

A safe React dangerouslySetInnerHTML alternative

Now, you may be concern of the property name because it has the word dangerous. And you should be alert.

If you’re the only one entering data, you should be at peace that the data wont be dirty.

But if the application or site is accepting data input from multiple people, than you may need to be a tad bit concern.

The goal is still to use the HTML string, but make it safer.

To achieve that, you can use an NPM module called DOMPurify.

Let’s pretend we have a dirty HTML string from an API.

You can use DOMPurify.sanitize() to remove any fishy code from a possible dirty string.


import DOMPurify from "dompurify";

const dirty = `I love to do evil <img src="http://unsplash.it/100/100?random" onload="alert('you got hacked');" />`;

const App = () => (
  <div
    dangerouslySetInnerHTML={{
      __html: DOMPurify.sanitize(dirty)
    }}
  />
);

If you’d like to learn about how to use DOMPurify with React and Node.js, checkout this article, “How to validate and sanitize user input in JavaScript“.

Oh wow, you’ve made it this far! If you enjoyed this article perhaps like or retweet the thread on Twitter:

I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!