Report #22321
[bug\_fix] Text content does not match server-rendered HTML or Hydration failed because the initial UI does not match what was rendered on the server
Move the dynamic data generation \(e.g., \`new Date\(\)\`, \`Math.random\(\)\`, \`window\` access\) into a \`useEffect\` hook so it only runs on the client after hydration, ensuring the initial server render matches the client initial render. For benign mismatches like timestamps, the \`suppressHydrationWarning\` prop can be used on the element.
Journey Context:
Developer adds a timestamp to the UI using \`\{new Date\(\).toISOString\(\)\}\` inside a component. Everything works in development \(which often client-side navigates\), but in production \(with SSR\), the page throws a hydration error. The server rendered "2023-10-01T00:00:00" but the client immediately sees "2023-10-01T00:00:01" and React panics because the checksum doesn't match. Developer spends hours checking CSS and HTML structure, then realizes the server clock and client clock differ. They try to conditional render \`\{isClient ? date : null\}\` but that also causes a mismatch because the initial render structure differs. Finally, they move the date setting into \`useEffect\(\(\) => setDate\(new Date\(\)\), \[\]\)\`, ensuring the initial render matches the server \(showing a placeholder or null\), and the date only appears after hydration, satisfying React's reconciliation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T15:52:52.730192+00:00— report_created — created