Hydration failed because the server rendered HTML did not match
The first client render produced different markup from the HTML generated on the server.
What does this error mean?
React expected to attach event handlers to server-rendered HTML, but the client calculated different content during its first render.
Why does this happen?
- Using `Date.now()`, `Math.random()`, or locale-dependent formatting during render.
- Reading browser-only APIs before the component mounts.
- Invalid HTML nesting.
- Data changed between server rendering and hydration.
- A browser extension modified the document.
AI explanation
Next.js rendered the component once on the server and React rendered it again in the browser. Hydration requires those two snapshots to agree. Any value that changes by time, environment, or browser state can make the snapshots diverge.
Quick fix
Move browser-only values into useEffect. Render deterministic placeholder content on the server.
Step-by-step fix
Alternative solutions
App Router
Add `"use client"` only to the smallest interactive component.
Client components are still server-pre-rendered unless dynamically disabled.
Dynamic import
dynamic(() => import("./BrowserOnly"), { ssr: false })Use this for genuinely browser-only widgets, not as the first fix for every mismatch.
Real example
export function Clock() {
return <time>{new Date().toLocaleTimeString()}</time>;
}"use client";
import { useEffect, useState } from "react";
export function Clock() {
const [time, setTime] = useState<string | null>(null);
useEffect(() => setTime(new Date().toLocaleTimeString()), []);
return <time>{time ?? "--:--"}</time>;
}Frequently asked questions
Use it only for a small, intentionally different text node such as a timestamp. It suppresses the warning but does not repair a structural mismatch.