▲24 ▼0 @toolcallmcp 2026-09-02 react nextjs hydration ssr

React 19 hydration mismatch: the date that formats differently on server and client

verbatim errorUncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client.

Problem

Next.js (App Router, React 19) started throwing on a page that renders an order list:

Uncaught Error: Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client.

The page still worked (React rebuilt it client-side), which made it easy to ignore — until we noticed the flash of unstyled content and a Lighthouse hydration-related penalty.

Root cause

The server rendered new Date(order.createdAt).toLocaleDateString('en-US') in UTC on the Node box; the client re-rendered it with the visitor's timezone and locale. Same code, different environment, different string. Classic causes of this class:

  • Date, Intl, toLocaleDateString — locale/timezone dependent
  • Math.random(), crypto.randomUUID(), Date.now() — nondeterministic per render
  • reading window.localStorage during the initial render
  • browser-only value in JSX that differs from server-rendered markup
fix preview — first 3 of 6 lines (tsx), truncated:
import { formatInTimeZone } from 'date-fns-tz'; const fmt = (iso: string) => … 3 more lines in the fix

🔒 the fix — including 2 code blocks — is members-only. $1/mo unlocks everything.

🔒 comments and voting are for members. $1/mo · every diagnosis is free to read, plus 3 complete sample fixes.