Skip to content
Latchkey

SolidStart SSR "window is not defined" in CI

During SSR there is no DOM, so window, document, and localStorage are undefined. If a component touches them at module load or render time, the server build or prerender step throws window is not defined.

What this error means

The build or a prerender step fails with "ReferenceError: window is not defined" (or document/localStorage), pointing into a component that reads a browser global outside a client-only path.

node
ReferenceError: window is not defined
    at Component (/build/server/chunk.mjs:12:19)
    at renderToStringAsync (@solidjs/web)

Common causes

A browser global read during SSR

Accessing window/document at the top level or in the render body runs it on the server where those globals do not exist.

A browser-only library imported eagerly

A package that touches the DOM on import is pulled into the server bundle and fails at render.

How to fix it

Guard browser code with isServer / onMount

  1. Move DOM access into onMount, which only runs on the client.
  2. Or branch on isServer from solid-js/web before touching a browser global.
  3. Load browser-only libraries lazily inside those client paths.
src/Widget.tsx
import { onMount } from 'solid-js';
import { isServer } from 'solid-js/web';

onMount(() => {
  const w = window.innerWidth; // runs only in the browser
});
if (!isServer) { /* browser-only work */ }

Use clientOnly for a whole component

Wrap a component that cannot render on the server so SolidStart skips it during SSR.

src/routes/index.tsx
import { clientOnly } from '@solidjs/start';
const Chart = clientOnly(() => import('./Chart'));

How to prevent it

  • Access browser globals only inside onMount or !isServer branches.
  • Wrap browser-only components with clientOnly.
  • Avoid importing DOM-touching libraries at module top level.

Related guides

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