Next.js "Hydration failed because the server rendered HTML didn't match" in CI
Next.js renders HTML on the server and React reuses it on the client. When the client's first render produces different markup, React throws a hydration error. In CI this can surface in tests or as a noisy, sometimes failing, build signal.
What this error means
The console or test run shows "Hydration failed because the server rendered HTML didn't match the client" or "Text content does not match server-rendered HTML", often tied to dates, random values, or browser-only checks.
Error: Hydration failed because the server rendered HTML didn't match the client.
As a result this tree will be regenerated on the client.
...
See more info here: https://nextjs.org/docs/messages/react-hydration-errorCommon causes
Non-deterministic values differ between server and client
Date.now(), Math.random(), or new Date().toLocaleString() produce different output on server and client, so the markup diverges.
Browser-only branching during the first render
Reading window or localStorage to decide markup makes the client's initial render differ from the server's.
How to fix it
Defer client-only differences to after mount
- Render the server-safe output on the first pass.
- Use
useEffectplus state to apply client-only values after hydration. - Re-run to confirm the first client render matches the server.
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
return <span>{mounted ? new Date().toLocaleString() : null}</span>Suppress hydration warnings for intentionally dynamic text
For a single element whose value is expected to differ (like a timestamp), opt out narrowly.
<time suppressHydrationWarning>{now}</time>How to prevent it
- Keep the first client render identical to the server render.
- Move non-deterministic and browser-only logic into effects.
- Fail CI on hydration errors in component tests to catch regressions.