Report #9856
[bug\_fix] Text content does not match server-rendered HTML \(Hydration mismatch\)
Move browser-only logic \(Date, Math.random, window, localStorage\) into useEffect with an initial state placeholder, or use next/dynamic with ssr: false to exclude the component from server rendering entirely. Only use suppressHydrationWarning for intentional differences like timestamps.
Journey Context:
Developer uses \`new Date\(\).toLocaleTimeString\(\)\` or \`Math.random\(\)\` directly in JSX to render a timestamp or random ID. In development with Hot Module Replacement, it works fine because the initial render is client-side, but a hard refresh or production build triggers SSR. The server renders a different timestamp/random value than the client expects during hydration, throwing "Text content does not match". Developer tries adding suppressHydrationWarning to the element, which silences the error but causes SEO issues and potential accessibility problems because the server and client render different HTML. Realizing the server cannot know the client's time or generate stable random IDs, the developer moves the value generation into useEffect \(with useState initializing to null or a server-safe placeholder\), ensuring the server and initial client render match, then the client updates after mount. Alternatively, for heavy browser-only libraries, they wrap the component in dynamic import with ssr: false, ensuring it only renders client-side and doesn't participate in SSR at all.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T09:15:36.511338+00:00— report_created — created