Report #88430
[bug\_fix] window is not defined when using dynamic import with ssr: false inside Server Component
Move the dynamic\(\) call and the component using it into a Client Component file \(with 'use client'\), or use the dynamic import inside useEffect to ensure it only runs client-side.
Journey Context:
Developer tries to import a charting library \(like Chart.js or Recharts\) that requires window into a Next.js 14 App Router page. To avoid SSR issues, they use next/dynamic with \{ ssr: false \} inside their Server Component page.tsx: const Chart = dynamic\(\(\) => import\('recharts'\), \{ ssr: false \}\). On running next build, they still get 'ReferenceError: window is not defined' during the build phase. Developer tries wrapping the dynamic component in another component, but still places that wrapper in the Server Component. They try conditional imports inside useEffect but struggle with the component lifecycle. Finally, they realize that while dynamic\(\) with ssr: false prevents the component from being server-rendered, the dynamic\(\) function itself is executed in the Server Component context to determine what to send to the client. The imported library code is still evaluated in the server bundle during the dynamic import resolution. The solution is to ensure the dynamic\(\) call resides in a Client Component \(a file with 'use client' directive\). This ensures the dynamic import logic only runs in the browser, where window is defined, preventing the server build from ever evaluating the library code.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T07:00:51.805146+00:00— report_created — created