Error: Hydration failed because the server rendered HTML didn't match the client
This happens when the HTML generated on the server differs from what React renders on the client. Common causes: using `Date`/`Math.random()` during render, browser extensions modifying the DOM, or missing `suppressHydrationWarning` on elements that legitimately differ (like formatted timestamps).
What causes this error
React hydration compares the server-rendered HTML against what it would render on the client. If they differ even slightly — a different timestamp, a random value, or content injected by a browser extension — React throws this warning and re-renders from scratch, hurting performance and sometimes causing visible flicker.
The Fix
Identify what differs between server and client. The three most common fixes:
// 1. Format dates consistently, or defer to client-only rendering
import { useEffect, useState } from 'react';
function Timestamp({ date }: { date: string }) {
const [formatted, setFormatted] = useState('');
useEffect(() => {
setFormatted(new Date(date).toLocaleString());
}, [date]);
return <span suppressHydrationWarning>{formatted}</span>;
}
// 2. Never call Math.random() or Date.now() directly during render
// 3. Check for browser extensions (Grammarly, password managers) injecting attributesCommon causes / variations
- Locale-dependent date/number formatting differing between server and browser timezone
- Conditionally rendering based on `typeof window !== 'undefined'` inside the render body
- Third-party scripts or browser extensions injecting DOM attributes before hydration
- Incorrect `'use client'` boundary placement causing server-only logic to leak into client render
Related errors
See also: params should be awaited (if the mismatch appears after a params-related refactor).
Comments
Loading comments...