12

First-off, I do know I should not nest <p> tags.

So I created a Next.js application and I have a component that sets rich text html as follows:

    <Typography
      dangerouslySetInnerHTML={{
        __html: richText
      }}
    />

The react component Typography is just a p tag in the end so this could simply be written as:

    <p
      dangerouslySetInnerHTML={{
        __html: richText
      }}
    />

So when the browser loads the page, my content does not show up and I am left with the console warning:

Warning: Prop 'dangerouslySetInnerHTML' did not match. Server: "" Client: "<p>...</p>"

After a lengthy debugging session, during cleaning up, using the <span> instead of <p> was the solution

    <span
      dangerouslySetInnerHTML={{
        __html: richText
      }}
    />

Nested p tags was a mistake, regardless, what is happening that makes Next.js not render this particular content resulting in the empty string Server: ""? Is Next.js just simply very sensitive to errors and warnings?

Karim
  • 415
  • 6
  • 14

5 Answers5

10

I've had the same problem because in the richtext I was getting <p> tags too, so when I switched my wrapping tag from <p> to <div> that error disappeared.

Barnee
  • 3,212
  • 8
  • 41
  • 53
2

I had the same issue, I solved this using react useState and useEffect hooks. so it's not rendering in the server.

import { useState, useEffect } from 'react';

export default function ParentComponent({ content }) {
   const [render, setRender] = useState(false);
   
   useEffect(() => {
      setRender(true);
   }, []);

   return <Typography dangerouslySetInnerHTML={{ __html: render && content }} />
}
Ruzky
  • 93
  • 6
2

Next.js will de-nest invalid html on the server so

<p> 
  <p>
     hello world
  </p>
</p>

becomes

<p></p>
<p> hello world </p>

so the HTML structure no longer matches the client rendered html hence rehydration fails

Sid
  • 846
  • 3
  • 12
  • 25
1

Material-UI have a prop called component. use component as div

<Typography {...other Typography Props} component="div" dangerouslySetInnerHTML={{
    __html: richText
  }}/>
Dipanjan Panja
  • 396
  • 4
  • 12
0

It depends on where richText is coming from. Is it possible that on the server-side render, richText = "", and then you make some API request on the front-end that sets the value of richText?

Tilo Mitra
  • 2,805
  • 1
  • 26
  • 20
  • No, that was my initial thought too but `richText` is not an empty string on the server side. I make the call in `getInitialProps` and I am 100% sure it is not an empty string. – Karim Oct 08 '19 at 04:45