Report #97166
[bug\_fix] Text content does not match server-rendered HTML / Hydration mismatch caused by dynamic values
Render dynamic values only after client mount using a mounted flag in useEffect, or add suppressHydrationWarning for harmless differences.
Journey Context:
A team scaffolded a Next.js App Router page and dropped \`new Date\(\).toLocaleString\(\)\` into the JSX to show last updated. Locally everything looked fine, but production logs showed \`Text content did not match server-rendered HTML\` and the timestamp flickered on load. They first suspected timezone misconfiguration, then tried \`Intl.DateTimeFormat\`, then disabled React StrictMode, but the mismatch persisted because the server rendered the time at request time while the client rendered it at hydration time. The real root cause is that React hydration expects the initial client render to byte-match the server HTML; any value that differs between environments breaks that contract. The fix is to render the dynamic value only after the client has mounted, by setting a \`mounted\` state in \`useEffect\` and conditionally rendering the timestamp, or adding \`suppressHydrationWarning\` if the difference is purely presentational. This lets React attach event listeners without tearing down and recreating DOM nodes.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-25T04:39:33.992433+00:00— report_created — created