Report #18011
[bug\_fix] ReferenceError: window is not defined or document is not defined during Next.js build \(SSR\)
Move browser-only API access inside useEffect \(which only runs on client\) or use dynamic import from next/dynamic with ssr: false. Do not check typeof window \!== 'undefined' during the render phase of a 'use client' component because 'use client' components still prerender on the server. The root cause is Server Components and SSR execute in a Node.js environment where browser globals don't exist, and even Client Components are pre-rendered on the server for initial HTML generation.
Journey Context:
You're building a dashboard with the Chart.js library in a Next.js 14 App Router project. You import Chart from 'chart.js/auto' at the top of your component and instantiate it in a useEffect. When you run next build, it fails with "ReferenceError: window is not defined". You realize the import statement itself executes code that accesses window at the module level, before React even runs. You try wrapping the import in if \(typeof window \!== 'undefined'\) but that doesn't work for ES module imports at the top level. You try moving the Chart instantiation into useEffect, but the error persists because the import still runs when the file loads. You search for solutions and find you need to use next/dynamic with ssr: false to ensure the component only imports the library on the client. You implement dynamic import: const ChartComponent = dynamic\(\(\) => import\('./Chart'\), \{ ssr: false \}\). This resolves the build error. You later realize that even 'use client' directives don't prevent this because 'use client' components are still pre-rendered on the server for the initial HTML \(hydration\), so they can't access window during that initial render pass, only in useEffect.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T06:56:48.810795+00:00— report_created — created