window is not defined Angular Origin: On your device Last updated 15 Oct 2026

Angular SSR: ReferenceError: window is not defined / document is not defined / localStorage is not defined

Code that only works in a browser ran during server-side rendering, where window, document and localStorage do not exist.

Exact message you may see ReferenceError: window is not definedReferenceError: document is not definedReferenceError: localStorage is not definedReferenceError: navigator is not definedwindow is not defined Angular SSR
Seen on: Angular Node.js TypeScript

Meaning

Angular SSR renders on Node. Browser globals are unavailable there. Wrap browser-only code with isPlatformBrowser, run it in afterNextRender, inject DOCUMENT instead of using document directly, and use abstractions for storage. Libraries that touch window at import time need lazy import or an SSR-safe alternative.

Common causes

  • Direct use of window, document, localStorage or navigator in components/services
  • Third-party library accessing window on import
  • Code in constructors or ngOnInit running on the server
  • Using ElementRef.nativeElement APIs that need a real DOM
  • Missing platform check around analytics/maps/charts

⚡ Quick fix

  1. Guard with isPlatformBrowser(inject(PLATFORM_ID))
  2. Move DOM work to afterNextRender()
  3. Inject DOCUMENT instead of the global document

Detailed fix by platform

Angular

  1. private platformId = inject(PLATFORM_ID); if (isPlatformBrowser(this.platformId)) { localStorage.setItem('k', 'v'); }
  2. afterNextRender(() => { this.chart = new Chart(...); });

Code examples

Browser-only code

typescript
import { PLATFORM_ID, afterNextRender, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

export class ThemeService {
  private platformId = inject(PLATFORM_ID);
  load() {
    if (isPlatformBrowser(this.platformId)) {
      return localStorage.getItem('theme');   // only runs in the browser
    }
    return null;
  }
}

How to diagnose

  1. Global — Which global is undefined?
  2. Source — Own code or a library import?
  3. Timing — Runs at construction or after render?

🔧 Still not fixed?

Many errors look alike. If the steps above didn’t solve it, one of these is probably what you’re facing:

Where this error sits

Origin: On your device. Errors that are often confused with or caused by this one (click to open):

Cannot find control with name — Angular: Error: Cannot find control with name: 'email' (reactive forms) (Angular)Cannot find control w…exceeded maximum budget — Angular build: Error: bundle initial exceeded maximum budget. Budget 1.00 MB was not met by 120.00 kB with a total of 1.12 MB (Angular)exceeded maximum budg…Hydration failed — Error: Hydration failed because the initial UI does not match what was rendered on the server (React)Hydration failedNG0500 — Angular SSR: NG0500: During hydration Angular expected <div> but found <span> (NG0501, NG0502) (Angular)NG0500Schema validation failed with the following errors — Angular CLI: Schema validation failed with the following errors: Data path "" must NOT have additional properties(xyz) (Angular)Schema validation fai…TDZ — ReferenceError: Cannot access 'x' before initialization (JavaScript)TDZUnhandledPromiseRejection — Node.js: [UnhandledPromiseRejection] — This error originated either by throwing inside of an async function without a catch block (Node.js)UnhandledPromiseRejec…window is…

Explore the map of this error Full error map →

🧠 Still stuck? Analyze your error

Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.

💬 What worked for others

No tips yet — did something else fix this for you?

Share what worked for you

Tips are checked by an editor before they appear. Links are removed.