Skip to content
Latchkey

Angular SSR/prerender "window is not defined" in CI

SSR and prerender execute your app in Node, where window, document, and localStorage do not exist. Code that touches a browser global at module load or during rendering throws a ReferenceError and fails the CI build step.

What this error means

ng build with prerender/SSR, or ng run app:prerender, fails with "ReferenceError: window is not defined" (or document/localStorage) and a stack trace inside your code.

prerender
ReferenceError: window is not defined
    at new AnalyticsService (main.server.mjs:1200:5)

Common causes

Browser globals accessed on the server

Code reads window/document/localStorage directly during construction or rendering, which has no meaning in the Node SSR environment.

A dependency that assumes a browser at import time

A library touches browser globals when imported, so merely loading it during SSR throws.

How to fix it

Guard browser access by platform

Use isPlatformBrowser so browser-only code runs only in the browser, not during SSR/prerender.

component.ts
constructor(@Inject(PLATFORM_ID) private platformId: object) {}
ngOnInit() {
  if (isPlatformBrowser(this.platformId)) {
    window.scrollTo(0, 0);
  }
}

Defer or lazy load browser-only dependencies

Import libraries that need a browser only in the browser code path, not at server module load.

How to prevent it

  • Gate all window/document access with isPlatformBrowser.
  • Avoid importing browser-only libraries in server-shared code.
  • Run prerender/SSR locally so these surface before CI.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →