Hydration mismatch xảy ra khi HTML do server render khác với HTML mà Vue render ở client — 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) chỉ tránh crash,
// KHÔNG hết mismatch: server render null còn client render giá trị localStorage.
// Muốn server và client khớp thì đọc cookie (được gửi kèm request):
const count = useCookie('count')
// 3. onMounted cho code chỉ chạy phía browser
onMounted(() => {
// An toàn — chỉ chạy ở 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.