SSR Pitfalls
Common SSR Issues and Solutions
Server-Side Rendering (SSR) brings many benefits, but also introduces challenges. Understanding these pitfalls helps you build robust Nuxt applications.
Hydration Mismatches
The most common SSR issue is when the server-rendered HTML doesn't match what Vue renders on the client:
<!-- ❌ Causes hydration mismatch -->
<template>
<div>{{ Date.now() }}</div>
</template>
Why? The timestamp is different on server vs client.
Solution: Use client-only rendering for dynamic values:
<!-- ✅ Correct approach -->
<template>
<ClientOnly>
<div>{{ Date.now() }}</div>
</ClientOnly>
</template>
Browser-Only APIs
Accessing window, document, or other browser APIs on the server causes errors:
<!-- ❌ Crashes on server -->
<script setup>
const width = window.innerWidth
</script>
Solutions:
<!-- ✅ Option 1: Use onMounted -->
<script setup>
const width = ref(0)
onMounted(() => {
width.value = window.innerWidth
})
</script>
<!-- ✅ Option 2: Check process.client -->
<script setup>
const width = import.meta.client ? window.innerWidth : 0
</script>
<ClientOnly> Component
Wrap client-only content in <ClientOnly>:
<template>
<div>
<h1>Always rendered</h1>
<ClientOnly>
<MapComponent />
<template #fallback>
<p>Loading map...</p>
</template>
</ClientOnly>
</div>
</template>
Lifecycle Hooks
Only certain hooks run on both server and client:
- ✅ Server & Client:
setup(),onServerPrefetch() - ❌ Client only:
onMounted(),onBeforeMount(),onUnmounted()
<script setup>
// ✅ Runs everywhere
console.log('Setting up...')
// ✅ Only runs on server (for data fetching)
onServerPrefetch(async () => {
await fetchData()
})
// ✅ Only runs on client
onMounted(() => {
console.log('Component mounted in browser')
})
</script>
Challenge
Fix the hydration mismatch in the provided component:
- The
BrokenComponenthas several SSR issues - find and fix them - Use
<ClientOnly>where appropriate - Use
onMounted()for browser-specific code - Ensure no hydration warnings in the console
Tip: Open the browser console and look for hydration mismatch warnings. They'll tell you exactly where the problem is.
If you get stuck, you can check the solution by clicking the button below.
SSR pitfalls are common but predictable. Follow these patterns, and you'll avoid most issues. Always test your components with SSR enabled!