Hydration mismatch xảy ra khi HTML do server render khác với những gì Vue client muốn render — Vue sẽ warning và re-render toàn bộ component.
Nguyên nhân phổ biến:
1. Browser-only APIs trong setup: localStorage, window, document không tồn tại trên server
2. Random/Date values: Math.random(), Date.now(), new Date() cho kết quả khác nhau
3. Conditional dựa trên user agent/cookies: server không có context này
4. Third-party directives chỉ chạy client-side
Fixes:
typescript
// 1. Dùng <ClientOnly> component trong Nuxt
<ClientOnly fallback-tag="span">
<ComponentThatUsesWindow />
</ClientOnly>
// 2. import.meta.client (Nuxt 3 idiom; process.client là Nuxt 2 legacy)
const count = ref(import.meta.client ? localStorage.getItem('count') : null)
// 3. onMounted cho browser-only code
onMounted(() => {
// Safe — only runs on client
state.value = localStorage.getItem('key')
})Lưu ý: Vue/Nuxt không có suppressHydrationWarning attribute (đó là React).
Để intentional mismatch dùng <ClientOnly> hoặc :key trick để force re-render.