{"id":416,"hash":"6473255a6bf7439903925ed16c0e4a1de3fab5e0106141d53d859ca7151b16d8","pattern":"Warning: Text content did not match. Server: &quot;I&#39;m out&quot; Client: &quot;I&#39;m in&quot; div","full_message":"I'm using universal-cookie in Next.js project and this the simple code that return a warning in console:\n\nimport React, { useState } from \"react\";\nimport Cookies from \"universal-cookie\";\nimport styles from \"../styles/Home.module.css\";\n\nexport default function Home() {\n  const cook = new Cookies();\n  const [session, setSession] = useState(cook.get(\"key\"));\n  const setCookie = () => {\n    cook.set(\"key\", \"hola\", { secure: true });\n    setSession(cook.get(\"key\"));\n  };\n  const deleteCookie = () => {\n    cook.remove(\"key\", { secure: true });\n    setSession(undefined);\n  };\n\n  return (\n    <div className={styles.container}>\n      <button onClick={() => setCookie()}>Save Cookie</button>\n      <button onClick={() => deleteCookie()}>Delete Cookie</button>\n      {session ? <>I'm in</> : <>I'm out</>}\n    </div>\n  );\n}\n\nWhen \"I'M IN\" and then I refresh the page the follow warning appear in console:\n\nI have already looked everywhere for a solution.","ecosystem":"npm","package_name":"reactjs","package_version":null,"solution":"Next.js pre-renders every page on the server.\n\nBy default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance,\ninstead of having it all done by client-side JavaScript.\nPre-rendering can result in better performance and SEO.\n\n(...) When a\npage is loaded by the browser, its JavaScript code runs and makes the\npage fully interactive (this process is called hydration in React).\n\n— Next.js, Building Your Application, Rendering\n\nThe hydration issue occurs because the HTML rendered on the browser doesn't match the one generated on the server. In your case this is because cook.get(\"key\") returns different things in both.\n\nThere are a couple of options to solve the issue.\n\n#1 Moving setting state to useEffect\nThe first solution is to move setting the state inside a useEffect. This forces the state to only be set on the client-side, so no mismatches will occur.\n\nexport default function Home() {\n    const cook = new Cookies();\n    const [session, setSession] = useState();\n    \n    // `setCookie` and `deleteCookie` code here\n\n    useEffect(() => {\n        setSession(cook.get(\"key\"));\n    }, []);\n\n    return (\n        <div className={styles.container}>\n            <button onClick={() => setCookie()}>Save Cookie</button>\n            <button onClick={() => deleteCookie()}>Delete Cookie</button>\n            {session ? <>I'm in</> : <>I'm out</>}\n        </div>\n    );\n}\n\n#2 Using next/dynamic with { ssr: false }\nAs an alternate solution, the issue can also be circumvented by dynamically importing  the React component with next/dynamic using { ssr: false }, wherever the component is used. This prevents the component from being included on the server, and dynamically loads it on the client-side only.\n\nconst Home = dynamic(\n    () => import('../components/Home'),\n    { ssr: false }\n)","confidence":0.95,"source":"stackoverflow","source_url":"https://stackoverflow.com/questions/66374123/warning-text-content-did-not-match-server-im-out-client-im-in-div","votes":77,"created_at":"2026-04-19T04:51:06.845218+00:00","updated_at":"2026-04-19T04:51:06.845218+00:00"}