2

If you use create-next-app and paste this code, you get a hydration error on the client when running the next dev server.

pages/index.js

export async function getServerSideProps(context) {
  const x = Math.random();
  const script = `
<script id="feed">
var d = document.createElement('div');
d.id = "${x}";
var s = document.getElementById('feed')
s.parentNode.insertBefore(d, s)
</script>`;
  return {
    props: { script }, // will be passed to the page component as props
  };
}

export default function Home({ script }) {
  return (
    <div>
      Hello world. Here is my SSR website.
      <div dangerouslySetInnerHTML={{ __html: script }}></div>
    </div>
  );
}

Browser Console:

next-dev.js?3515:25 Warning: Prop `dangerouslySetInnerHTML` did not match. Server: "\n<div id=\"0.2796943840164239\"></div><script id=\"feed\">\nvar d = document.createElement('div');\nd.id = \"0.2796943840164239\";\nvar s = document.getElementById('feed')\ns.parentNode.insertBefore(d, s)\n</script>" Client: "\n<script id=\"feed\">\nvar d = document.createElement('div');\nd.id = \"0.2796943840164239\";\nvar s = document.getElementById('feed')\ns.parentNode.insertBefore(d, s)\n</script>"
    at div
    at div
    at Home (webpack-internal:///./pages/index.js:11:24)
    at MyApp (webpack-internal:///./pages/_app.js:37:27)
    at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:20638)
    at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/client.js:8:23179)
    at Container (webpack-internal:///./node_modules/next/dist/client/index.js:323:9)
    at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:825:26)
    at Root (webpack-internal:///./node_modules/next/dist/client/index.js:949:27) 

See more info here: https://nextjs.org/docs/messages/react-hydration-error

I know that the server is not inserting the div server-side, because the HTML response from a curl localhost:3000 gives me the HTML with no div inserted.

My theory is that the browser parses the script tag from the HTML response, and inserts the div before the app hydrates, leading to a mismatch.

My question is why would this error not happen in a production build? The error doesn't occur when running on a NextJS production server.

Regan Karlewicz
  • 176
  • 2
  • 10

1 Answers1

-1

using react useState and useEffect hooks. so it's not rendering in the server. you can use this code :

import { useState, useEffect } from 'react';

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

   return 
 (
<div>
  Hello world. Here is my SSR website.
  <div dangerouslySetInnerHTML={{ __html: script }}></div>
</div>
  );
}

OR

use can use nextjs dynamic import

Sooraj s
  • 17
  • 3
  • 8
  • I understand that you can render on the client in this manner, but the question is why the error doesn't occur in a production build. Other hydration errors from `dangerouslySetInnerHTML` print a minified stack trace in production builds, like in the case of an invalid HTML nesting. This hydration error in my example doesn't appear to be an issue when in a production build, there are no errors output from the console. – Regan Karlewicz Apr 26 '22 at 03:52
  • Please stop advertising for people using dangerouslySetInnerHTML you're just asking them to get hacked – Elyx0 Aug 18 '22 at 00:54
  • 2
    @Elyx0 I am not advertising or suggesting that people use `dangerouslySetInnerHTML`. There are valid use cases for it in specific applications, when you know you can trust the content being set. My use case is one of those. – Regan Karlewicz Aug 19 '22 at 18:16