Report #12192
[bug\_fix] ReferenceError: window is not defined during server-side rendering
Move browser-only code inside \`useEffect\` \(which only runs on the client after hydration\), or use \`next/dynamic\` with \`ssr: false\` to dynamically import the component only on the client, or guard with \`typeof window \!== 'undefined'\`.
Journey Context:
Developer installs a library like \`chart.js\`, \`mapbox-gl\`, or uses \`window.localStorage\` directly in a component. They write \`const width = window.innerWidth\` at the top level of the component or inside a \`useEffect\` but outside the callback. When running \`next build\` or refreshing the page in dev, they get "ReferenceError: window is not defined" or "document is not defined". The error stack points to the line accessing \`window\`. Developer realizes Next.js pre-renders pages on the server during build \(SSG\) or request \(SSR\), where Node.js runs and browser APIs like \`window\` don't exist. They try to fix it by checking \`if \(typeof window \!== 'undefined'\)\` before the access, but if this is used during the initial render, it causes a hydration mismatch \(server renders nothing, client renders something\). The correct fix is to use \`useEffect\`, which only executes after the component mounts in the browser, ensuring \`window\` exists. For heavy libraries that shouldn't be bundled for server, they use \`next/dynamic\` with \`ssr: false\` to lazy-load the component only on client. This works because it prevents the server from executing code referencing missing browser globals.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T15:18:03.150236+00:00— report_created — created