Skip to content

SSR Compatibility

VitePress is a static site generator (SSG) that works by rendering each page into static HTML through server-side rendering (SSR) at build time. This means your Vue component code will run not only in the browser (client side) but also in the Node.js environment (server side).

Therefore, you need to ensure your code is isomorphic, meaning the same code can run correctly in both environments. This is commonly referred to as "SSR compatibility."

Browser/DOM-specific APIs

The most common SSR incompatibility issue is directly accessing global variables that exist only in the browser, such as window or document.

Incorrect Example:

javascript
// In a component's <script setup> or created() hook
// This will throw an error during build time (Node.js environment)
// because Node.js doesn't have a window object
const width = window.innerWidth;

Correct Approach:

Move code that accesses browser-specific APIs to lifecycle hooks that only execute on the client side, most commonly onMounted.

vue
<script setup>
import { ref, onMounted } from 'vue'

const width = ref(0)

// onMounted hook only executes after the component is mounted to the DOM
// (i.e., in the browser)
onMounted(() => {
  width.value = window.innerWidth
})
</script>

Helper Tools Provided by VitePress

VitePress provides some built-in helper tools to help you handle SSR compatibility issues.

<ClientOnly /> Component

If you have a component that's not compatible with SSR, or you only want it to render on the client side (for example, a component with heavy interaction that's not important for SEO), you can use the <ClientOnly /> component to wrap it.

vue
<template>
  <div>
    <p>This content will be SSR rendered.</p>
    <ClientOnly>
      <!-- This content and its child components will only render on the client side -->
      <MyInteractiveComponent />
    </ClientOnly>
  </div>
</template>

inBrowser Constant

VitePress provides an inBrowser constant that you can use to conditionally execute code that should only run in the browser.

vue
<script setup>
import { inBrowser } from 'vitepress'

if (inBrowser) {
  // Code here will only execute in the browser environment
  const geo = navigator.geolocation;
}
</script>

Third-party Library Compatibility

When using third-party libraries, also pay attention to their SSR compatibility. Some libraries may assume they only run in the browser environment.

Handling Techniques:

  1. Check Documentation: Check if the library's documentation mentions SSR or usage with Nuxt/Next.js/VitePress.

  2. Dynamic Import: If a library is not compatible with SSR, you can dynamically import() it in the onMounted hook to ensure it's only loaded and executed on the client side.

    vue
    <script setup>
    import { onMounted } from 'vue'
    
    onMounted(async () => {
      const SomeLibrary = (await import('some-non-ssr-library')).default
      // Now you can use SomeLibrary here
      const instance = new SomeLibrary()
    })
    </script>

Ensuring code SSR compatibility is a key step when using VitePress or any modern frontend framework for static site generation. It can avoid build errors and ensure your website is successfully pre-rendered.

Content is for learning and research only.