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
273
Related Errors
ENOENT
Node.js
ENOENT: No Such File or Directory
The operating system cannot find the specified file or directory.
ERESOLVE
JavaScript
npm ERESOLVE Unable to Resolve Dependency Tree
npm cannot install a package due to conflicting dependency requirements.
Node.js
Unhandled Promise Rejection
A Promise was rejected but no error handler was attached to catch the rejection.
Frontend
WebSocket Connection Failed
The WebSocket connection could not be established or was closed unexpectedly.