Report #9659
[bug\_fix] ReferenceError: window is not defined / document is not defined / navigator is not defined during Next.js build \(SSR\)
Import the browser-only library or component using \`next/dynamic\` with the \`ssr: false\` option to ensure it is only loaded on the client. Alternatively, move the import and usage into a Client Component \('use client'\) and ensure the component only mounts after useEffect confirms client-side execution. For third-party scripts, use the built-in Next.js Script component with the appropriate loading strategy.
Journey Context:
Developer installs a charting library like \`recharts\`, \`chart.js\`, or a mapping library like \`leaflet\` for a Next.js App Router project. Creates a component \`Chart.tsx\` that imports the library at the top: \`import \{ LineChart \} from 'recharts'\`. Uses the component in a page. Runs \`next build\`. The build fails with "ReferenceError: window is not defined" or "document is not defined" during the server-side rendering phase. Developer tries adding \`if \(typeof window \!== 'undefined'\)\` guards around the component usage, but the error persists because the \`import\` statement itself executes at module load time in Node.js, accessing browser globals before the component renders. Developer tries marking the file with 'use client', but in App Router this still executes during SSR for initial HTML generation. Eventually discovers \`next/dynamic\` with the \`ssr: false\` option: \`const Chart = dynamic\(\(\) => import\('../components/Chart'\), \{ ssr: false \}\)\`. This ensures the library is only imported and executed in the browser, completely skipping the import during the Node.js build/SSR phase. The build succeeds and the chart only renders client-side.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T08:45:19.387361+00:00— report_created — created