Report #97670
[bug\_fix] Accessing \`window\` or \`document\` in a Server Component \(or during SSR\) throws 'window is not defined'
Move any browser-only code into a \`useEffect\` \(inside a \`'use client'\` component\) or guard with \`typeof window \!== 'undefined'\`. For libraries that require \`window\`, use \`next/dynamic\` with \`ssr: false\`.
Journey Context:
I was integrating a charting library \(Chart.js\) that auto-attaches to the global \`window\` on import. I imported it at the top of a page component \(\`page.tsx\`\) inside the App Router \(which is a Server Component by default\). The build failed with 'ReferenceError: window is not defined'. I was confused because the import seemed fine locally. The problem: Server Components render on the server where there is no \`window\` object. Even if the library is never called, the import itself executes the library's top-level code, which references \`window\`. The fix was to dynamically import the library client-side using \`next/dynamic\` with \`\{ ssr: false \}\`. Alternatively, I could have moved the import inside a \`useEffect\` in a Client Component. I created a wrapper client component that dynamically imports the chart and renders it only after mount. The root cause: SSR executes JavaScript on the Node.js runtime, which lacks browser globals.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-25T15:49:56.745663+00:00— report_created — created