Report #77228
[bug\_fix] Text content does not match server-rendered HTML / Hydration failed because the initial UI does not match
Ensure deterministic rendering between server and client. For timestamps, format consistently or render date-only content after hydration using useEffect. For browser extensions \(Grammarly, LastPass\) injecting DOM nodes, add the \`suppressHydrationWarning\` prop to the affected element, or move dynamic content into a client-only component mounted via useEffect.
Journey Context:
Developer adds a timestamp showing "Last updated: \{new Date\(\).toLocaleString\(\)\}" to a Next.js page. Locally in dev mode it works, but production builds log "Text content does not match". Inspecting the HTML reveals the server rendered UTC time while the client rendered local time, causing a text node mismatch. Developer tries to fix by formatting the date identically, but now Grammarly extension injects a \`\` element into the paragraph, changing the DOM tree structure and throwing a different hydration error about extra nodes. After searching the error message, developer finds that adding \`suppressHydrationWarning\` to the span silences the warning for unavoidable cases, but the robust fix is to only render the timestamp after mount: useState\(false\) \+ useEffect\(\(\) => setMounted\(true\), \[\]\) and conditionally render the date only when mounted, ensuring server and client HTML match initially.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T12:13:18.911783+00:00— report_created — created