J. Pedro Ribeiro

How to fix 'dangerouslySetInnerHTML did not match' error in React.js

December 27, 2022

console.log error message on a browser

This is an issue I come across every once in a while and it always takes me a couple hours to figure it out.

Replicating the issue

Let's say you have a React.js component that will render a paragraph of text coming from a CMS and that content can have HTML tags in it, like a WYSIWYG editor.

// MyTextComponent.js
function MyTextComponent(props) {
  return <p dangerouslySetInnerHTML={{ __html: props.content }} />;
}

// App.js
function App(props) {
  return (
    <div>
      <MyTextComponent content={props.content} />
    </div>
  );
}

The browser renders what you expect:

browser rendering the component

However, there's that warning in the console that says:

Warning: Prop `dangerouslySetInnerHTML` did not match. Server: "" Client: "<p>This is my paragraph.</p>" 

If you're using Next.js, you will get a nicer error message:

Next.js error message

What causes this warning?

On my example, the content passed to the component was <p>This is my paragraph.</p> which would be fine considering that we are using dangerouslySetInnerHTML to render the content.

However, the component is already wrapping the content in a <p> tag which, according to the HTML Spec, should only contain phrasing content.

The spec also says:

Paragraphs are block-level elements, and notably will automatically close if another

Here is a CodePen that illustrates and replicates this condition more clearly:

If you inspect the rendered paragraph, you will see the following:

paragraph with invalid nested tags

Which doesn't match what the server rendered <p>This is my paragraph.</p>.

How to fix it?

One solution is to change the wrapping element to a <div> instead of a <p>.

// MyTextComponent.js
function MyTextComponent(props) {
  return <div dangerouslySetInnerHTML={{ __html: props.content }} />;
}   

The main point is to ensure that the rendered content is valid HTML.


J. Pedro Ribeiro

Hello!
I’m a Brazilian front-end developer living in London. This website features some of my latest projects and my thoughts on anything web related.
You can find me on Twitter, Instagram, and LinkedIn.
Wanna talk? Send me a message.