Skip to content
Latchkey

VitePress "window is not defined" on build in CI

VitePress prerenders each page in Node during the build, where window and document do not exist. A theme component or imported module that reads a browser global at render time crashes the build.

What this error means

vitepress build fails with "ReferenceError: window is not defined" (or document/localStorage), often pointing at a custom component or a third-party import.

vitepress
build error:
ReferenceError: window is not defined
    at .vitepress/theme/Analytics.vue ... mounted/setup reading window.location

Common causes

Browser globals accessed during SSR

A component reads window in setup or at module scope, which runs server-side while VitePress prerenders.

A client-only library imported at build time

An imported package touches window on import, breaking the prerender even if you never call it server-side.

How to fix it

Access browser globals only on the client

Read window inside onMounted (which runs only in the browser) or guard with an environment check.

.vitepress/theme/Analytics.vue
import { onMounted } from 'vue';
onMounted(() => { const path = window.location.pathname; });

Render the component client-side only

Wrap a browser-only component in <ClientOnly> so it is skipped during prerender.

docs/index.md
<ClientOnly>
  <Analytics />
</ClientOnly>

How to prevent it

  • Use onMounted for any browser-global access.
  • Wrap browser-only components in <ClientOnly>.
  • Guard module-level reads with an environment check.

Related guides

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