Hydration Mismatch (SSR)
The server-rendered HTML doesn't match what the client-side JavaScript expected to render.
Explanation
Hydration mismatch occurs in server-side rendering (SSR) frameworks like Next.js, Nuxt, or Inertia.js when the HTML generated on the server differs from what the client-side JavaScript would generate. This causes the client to re-render the entire component tree, negating SSR performance benefits. Common causes include using browser-only APIs on the server (window, document), rendering random/dynamic content that differs between server and client, using Date.now() or Math.random(), and conditional rendering based on client-side state.
Common Causes
- Using browser-only APIs on server
- Dynamic content differing between server/client
- Date/time rendering differences
- Random values without fixed seed
- Conditional rendering based on client state
Solution
Ensure server and client render identical content by avoiding browser-only APIs during initial render. Use useEffect() or componentDidMount() for browser-specific code. Seed random generators with the same value on server and client. Wrap browser-only components with dynamic imports and ssr: false. Use suppressHydrationWarning for intentional differences (e.g., timestamps). In Next.js, use next/dynamic with ssr: false for client-only components. In Nuxt, use <client-only> wrapper component.
Code Example
// This causes hydration mismatch
function Clock() {
return <div>{new Date().toLocaleString()}</div>; // different on server!
}
// Fix: render empty on server, update on client
function Clock() {
const [time, setTime] = useState('');
useEffect(() => {
setTime(new Date().toLocaleString());
}, []);
return <div>{time}</div>;
}
// Next.js: dynamic import with no SSR
import dynamic from 'next/dynamic';
const InteractiveWidget = dynamic(
() => import('./InteractiveWidget'),
{ ssr: false }
);
// Nuxt: client-only component
<template>
<client-only>
<InteractiveWidget />
</client-only>
</template>
// Inertia.js: use only property for client rendering
<div>
{{ \Carbon\Carbon::now()->format('Y-m-d') }}
</div>
Error Information
Language
javascript
Difficulty
Intermediate
Views
131
Related Errors
ECONNREFUSED
Database
ECONNREFUSED
The network connection was refused by the target server.
Frontend
Invalid CSS Property
The code sets a CSS property that doesn't exist or uses incorrect syntax.
Frontend
ResizeObserver Loop Limit Exceeded
A ResizeObserver callback triggered layout changes that caused another resize, creating an infinite loop.
Frontend
Invalid DOM Property
The code uses an incorrect HTML attribute or React-specific prop on a DOM element.