Skip to main content

SSR Compatibility

VitePress pre-renders the application in Node.js during build, generating static HTML. This means your code must be compatible with server-side rendering (SSR).

Understanding SSR in VitePress

During build, VitePress:
  1. Runs your code in Node.js (SSR)
  2. Calls renderToString() from Vue’s server renderer
  3. Generates static HTML files
  4. Hydrates on the client side
Reference: /home/daytona/workspace/source/src/client/app/ssr.ts:6

Browser-Only APIs

Using import.meta.env

Check the environment before accessing browser APIs:

The inBrowser Helper

VitePress provides an inBrowser constant:
Reference: /home/daytona/workspace/source/src/shared/shared.ts:35

Client-Only Components

Using ClientOnly Component

Wrap components that rely on browser APIs:

How ClientOnly Works

Reference: /home/daytona/workspace/source/src/client/app/components/ClientOnly.ts:1
ClientOnly renders nothing during SSR and only renders content after the component is mounted on the client.

Async Component Loading

Load components dynamically on the client:

defineClientComponent API

Reference: /home/daytona/workspace/source/src/client/app/utils.ts:84

Lifecycle Hooks

1

Avoid beforeMount and mounted during SSR

These hooks only run on the client:
2

Be careful with setup()

setup() runs on both server and client:

Common SSR Issues

Accessing window/document

localStorage/sessionStorage

CSS-in-JS Libraries

Many CSS-in-JS libraries need special SSR handling:

Router and Navigation

Safe Route Access

The router is available on both server and client:
Reference: /home/daytona/workspace/source/src/client/app/router.ts:248

Location Hash

Be careful with location.hash during SSR:
Or use VitePress’s reactive hash:

Third-Party Libraries

Checking Library Compatibility

Libraries that immediately access browser APIs during import will break SSR.

Option 1: Dynamic Import

Option 2: Conditional Import

Option 3: Vite’s SSR Externals

.vitepress/config.js

Environment Variables

VitePress exposes environment info via import.meta.env:
Reference: /home/daytona/workspace/source/src/client/app/router.ts:112

Testing SSR Compatibility

Check browser console for hydration mismatches.
  • ReferenceError: window is not defined - Using browser API during SSR
  • ReferenceError: document is not defined - Accessing DOM during SSR
  • Hydration mismatch - Server and client render different content
Enable Vue’s hydration mismatch details:
.vitepress/config.js