--- title: Understand and Fix SSR Hydration Mismatches impact: HIGH impactDescription: Hydration mismatches cause visual flickering, performance loss, and broken functionality type: gotcha tags: [vue3, ssr, hydration, debugging, nuxt, server-side-rendering] --- # Understand and Fix SSR Hydration Mismatches **Impact: HIGH** - Hydration mismatches occur when the HTML rendered on the client differs from what the server rendered. Vue attempts to recover by discarding and re-rendering mismatched nodes, causing performance degradation, visual flickering, and potentially broken event handlers. Understanding the common causes helps you prevent and debug these issues effectively. ## Task Checklist - [ ] Validate HTML structure for proper nesting (no div in p, no nested a tags) - [ ] Move random value generation to onMounted or use seeded randoms - [ ] Format dates/times on client side only - [ ] Use `data-allow-mismatch` (Vue 3.5+) for intentional mismatches - [ ] Check for browser-modified HTML in dev tools ## Cause 1: Invalid HTML Nesting Browsers auto-correct invalid HTML, creating different DOM than Vue expects. **Incorrect:** ```vue ``` Browser converts the first example to: ```html

This will break hydration

``` **Correct:** ```vue ``` ## Cause 2: Random Values in Render Server and client generate different random values. **Incorrect:** ```vue ``` **Correct - Client-Only Random:** ```vue ``` **Correct - Seeded Random:** ```javascript // utils/seededRandom.js export function createSeededRandom(seed) { return function() { seed = (seed * 9301 + 49297) % 233280 return seed / 233280 } } // Use same seed on server and client const seed = 12345 // Could be based on user ID, page, etc. const random = createSeededRandom(seed) ``` ## Cause 3: Timezone and Date Differences Server may be in different timezone than client. **Incorrect:** ```vue ``` **Correct:** ```vue ``` ## Cause 4: Browser Extensions and Modifications Browser extensions can inject content into the DOM. **Mitigation:** ```vue ``` ## Vue 3.5+ Suppressing Intentional Mismatches ```vue ``` Valid `data-allow-mismatch` values: - `text` - Text content mismatches - `children` - Child element mismatches - `class` - Class attribute mismatches - `style` - Style attribute mismatches - `attribute` - Other attribute mismatches - (no value) - All mismatches ## Debugging Hydration Mismatches ```javascript // Enable detailed hydration mismatch warnings in development // vite.config.js export default { define: { __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: true } } ``` ```vue ``` ## Common Error Messages | Error | Likely Cause | |-------|--------------| | "Hydration text content mismatch" | Different text on server/client (dates, random) | | "Hydration children mismatch" | Invalid HTML nesting, conditional rendering | | "Hydration attribute mismatch" | Dynamic attributes with different values | | "Hydration node mismatch" | Completely different elements rendered | ## Reference - [Vue.js SSR Guide - Hydration Mismatch](https://vuejs.org/guide/scaling-up/ssr.html#hydration-mismatch) - [Nuxt Hydration Best Practices](https://nuxt.com/docs/guide/best-practices/hydration) - [data-allow-mismatch RFC](https://github.com/vuejs/core/pull/9562)