68

I'm using the React 16 beta (react-fiber) with server side rendering

What I am to understand this to mean?

warning.js:36 Warning: Did not expect server HTML to contain a <div> in <div>.
David Furlong
  • 1,343
  • 1
  • 12
  • 15
  • 6
    Where is this happening? a code where you encountered the error could be help full – abdul Jul 27 '17 at 12:08
  • I don't think my code would be particularly helpful. I'm rendering server side and sending an html string to the client as a response. This is standard across any react SSR approaches – David Furlong Jul 27 '17 at 13:11
  • Likely related to "The server renderer has been completely rewritten, and now offers a streaming mode (it's currently exposed via react-dom/node-stream). Server rendering does not use markup validation anymore, and instead tries its best to attach to existing DOM, warning about inconsistencies. This server renderer code is still very new, so it is likely to have issues. Please report them." https://github.com/facebook/react/issues/10294 – David Furlong Jul 27 '17 at 13:23
  • I followed this url and solved my issue. https://blog.jannikwempe.com/react-pre-rendering-and-potential-hydration-issue – ArifMustafa Sep 13 '21 at 15:11

10 Answers10

55

Just change express response from

<body>
    <div id="root">
        ${markup}
    </div>
</body>

to

<body>
    <div id="root">${markup}</div>
</body>

Remove space between tags

Sagar
  • 4,473
  • 3
  • 32
  • 37
  • 15
    Can you please explain why would you suggest this solution? – Pbd Jul 24 '18 at 05:21
  • 9
    This problem is occurred when you have tried to rehydrate you react app. Generated react app rehydrate with generated markup at that time it show empty space between jsx tags. checkout this link https://reactjs.org/docs/react-dom.html#hydrate – Sagar Jul 24 '18 at 05:37
  • 2
    Thank you! I wasted 2 days with this problem, and none of the solutions were good. – Nick Isaacs Aug 25 '18 at 04:29
  • 2
    This should be the accepted answer. The current one just tells what the issue is without giving a solution. – MustSeeMelons Oct 05 '20 at 12:16
  • Formatting code like this looks more like a workaround to me. – Tobi G. Aug 03 '22 at 09:54
  • This is super weird. I am using prettier and while prettifying based on current rules, it moves the variable to next line if the tag has many tailwind `classNames`. This is not a great solution. – Arjun Nayak Aug 01 '23 at 19:30
40

Looking for that error in the react code it seems that this happens when the SSR html can't be rehydrated.

https://github.com/facebook/react/blob/7a60a8092144e8ab2c85c6906dd4a7a5815cff1f/src/renderers/dom/fiber/ReactDOMFiberComponent.js#L1022

So you are somehow initially rendering a different tree on the client vs the server.

w00t
  • 17,944
  • 8
  • 54
  • 62
  • 12
    Warning name `warnForDeletedHydratableElement` and message `Did not expect server HTML to contain a ...`. The warning could be definitely more verbose... – Darkowic Jun 07 '18 at 08:24
  • 2
    Can you clarify what you mean by "initially rendering a different tree on the client vs the server." I have the same problem and I can't figure out any solution? – E.Omar Jun 06 '20 at 16:44
  • 2
    @e.omar i use context to pass around an SSR variable. On the server it's set to true, and on the client it's true for the first render and then set to false. – w00t Jun 07 '20 at 18:52
  • If you are using **next.js** and the error context contains the use of **next router**, React.useEffect, SWR, mutate, etc. You may have a look at [this comment](https://github.com/vercel/next.js/discussions/11484#discussioncomment-356055). The warning may caused by the router. – Ggicci Jan 12 '22 at 06:08
9

This is odd but for me the issue was my password manager extension (LastPass) injecting some HTML where I have some input fields... I disabled the extension and the error was gone ‍♂️

JV Lobo
  • 5,526
  • 8
  • 34
  • 55
  • LastPass strikes again! – Derrick Miller Jul 09 '23 at 07:11
  • Same here! Hard to believe that could be the case. – ankush981 Jul 23 '23 at 19:31
  • Jesus! Thanks guys! Lost wayyy to much time because of LastPass' extension... Disabling it solved the issue. -- To note that I also have 1password's extension in parallel and that one didn't cause any issue. – alainschaller Aug 09 '23 at 23:41
  • Currently, you do not have to disable the LastPass extension, you can also disable automatically form filling (the icon will not be shown in an input). Although LastPass should fix this behavior. – DHFW Aug 28 '23 at 15:44
4

I faced the same warning while using Modal in Next.js. I was working to create a popup on the main page.

I found a solution. If the modal show state comes true first, it produces this warning. So I made it first undefined then I set it true after the page rendered . The code is below.

 const [modalShow, setModalShow] = React.useState();
  useEffect(() => {
    if ( modalShow === undefined ) {
      setModalShow(true)
    }
  }, [modalShow])
AhuraMazda
  • 460
  • 4
  • 22
2

I had this issue, I solved it where I changed this:

<div>
    <Header />
    {children}
</div>

to this:

<div>
    <Header />
    <div>{children}</div>
</div>
Ethan
  • 21
  • 1
1

My issue was react-loadable: The code used LoadableComponent for client only which wrapped each of my React-Component in client.

The cause was hard to find because Client and Server rendered the same HTML.

My Solution:

  1. upgrade to node 16.x
  2. remove react-loadable
  3. load all components using import
Tobi G.
  • 1,530
  • 2
  • 13
  • 16
0

I had the same fault, i was trying some stuff and added html element directly to the root layout.

return (
    <html lang="en">
      <body>
        {children}
        //was added here some html element who gives the error
      </body>
    </html>
  );
Producerey
  • 26
  • 3
0

The placeholder property on an <input /> tag also triggers this error... even in a static HTML component. Apparently, there must be an initial state in the browser that causes the mismatch. I guess I'll set that after load, how lame!

doublejosh
  • 5,548
  • 4
  • 39
  • 45
0

I'm using Next.js 12. In this case, stopping the dev server, deleting the .next directory, and restarting the dev server solved the issue.

This happened following a fix that I did to some Styled Components. I guess something was off with the Next.js cache following the fix, so deleting it helped.

0

I am developing my project with Next.js in version 13.4.4, and at the moment of entering an <input/> in my component I was getting this header error.

However, when looking at the Dom of my browser, I found that I was automatically adding a <div></div> from the lastPass application, which is a password management extension.

enter image description here

I removed the extension and was able to fix the error, and everything works perfectly so far.

starball
  • 20,030
  • 7
  • 43
  • 238