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:
// 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.
<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.
<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.
<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:
Check Documentation: Check if the library's documentation mentions SSR or usage with Nuxt/Next.js/VitePress.
Dynamic Import: If a library is not compatible with SSR, you can dynamically
import()it in theonMountedhook 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.