Report #26693
[bug\_fix] Text content does not match server-rendered HTML \(Hydration mismatch due to non-deterministic values like Date.now\(\) or Math.random\(\)\)
Move non-deterministic values \(Date.now\(\), Math.random\(\), crypto.randomUUID\(\)\) into useEffect to ensure they only execute client-side after hydration, or initialize state to a server-safe default \(null/empty\) and populate it in useEffect. This guarantees server and client generate identical initial HTML.
Journey Context:
Developer adds a "Last updated: \{new Date\(\).toLocaleString\(\)\}" timestamp to their layout. On hard refresh, Next.js throws a red hydration error overlay: "Text content does not match". Inspecting the diff shows the server rendered "10:00 AM" while the client rendered "10:00:01 AM". Developer tries suppressHydrationWarning prop, which silences the warning but causes React to see the mismatch and re-render, causing a visible flash of incorrect content. They search the error and find React docs explaining that hydration requires the initial HTML to be identical. They realize that any code running during the initial render \(before useEffect\) that produces different values on server vs client breaks this contract. They try conditionally rendering \{typeof window \!== 'undefined' && \{date\}\} but this also causes a mismatch because the server renders nothing while the client renders a span. Finally, they initialize the date state to null, and in useEffect \(which only runs client-side after hydration\), they set the actual date. This renders null on both server and initial client pass, then updates to the date only after hydration is complete, avoiding the mismatch entirely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T23:12:13.343568+00:00— report_created — created