The error message "hydration failed because the initial UI does not match what was rendered on the server" occurs when the React client-side tree tries to attach to a different HTML structure than what was pre-rendered on the server. This mismatch disrupts the hydration process, causing React to fail to properly attach event handlers and make the app interactive
Common Causes of Hydration Mismatch
- Incorrect HTML nesting : For example, a
<div>
inside a<p>
, or interactive elements nested improperly (like<a>
inside another<a>
) can cause differences between server and client rendering
- Conditional rendering differences : Using browser-only APIs (like
window
orlocalStorage
) or checks liketypeof window !== 'undefined'
during rendering can cause the server and client to render different content
- Time-dependent or random values : Using
new Date()
orMath.random()
directly in render causes server and client to output different content because the values differ at render time
- Third-party libraries or component libraries that render differently on server and client
- Browser extensions or CDN modifications that alter the HTML between server and client
How to Fix Hydration Errors
- Ensure consistent rendering on server and client : Components should render the same HTML initially on both sides. Avoid using browser-only APIs or time-dependent values directly in the render phase
- Use
useEffect
for client-only logic: Move client-specific rendering or state updates intouseEffect
, which only runs on the client after hydration, preventing mismatches
jsx
import { useState, useEffect } from 'react';
export default function App() {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
return <h1>{isClient ? 'Client content' : 'Server content'}</h1>;
}
- Disable SSR for problematic components : In Next.js, use dynamic imports with
{ ssr: false }
to prevent server-side rendering of components that cause mismatches
- Fix HTML nesting issues : Correct invalid HTML structures that browsers may tolerate but servers do not
- Use
suppressHydrationWarning
for minor unavoidable differences: This React prop silences warnings when content differs but should be used sparingly
- Conditionally render time-dependent content : For example, render a placeholder on the server and the actual date/time on the client after hydration
Summary
Hydration errors arise because the server-rendered HTML and the client-
rendered React tree do not match exactly. The main solution is to ensure that
the initial render output is identical on both server and client by avoiding
browser-only APIs, fixing HTML structure, and deferring client-specific
rendering to useEffect
or disabling SSR for certain components