--- title: How to prevent flash before hydration nav_title: Preventing Flash description: Learn how to correct server-rendered content before the browser paints, avoiding visible flash when the page hydrates. --- User preferences, browser settings, and client-side storage aren't available during server rendering. The server emits a reasonable default, but any UI that depends on client-only state (locale, timezone, theme, persisted interactions) needs to be updated before the user sees it. Some common approaches to this problem: - A Client Component that re-renders with client values causes a hydration error. - Deferring to `useEffect` avoids the error but introduces a visible flash. - Rendering only on the server means giving up on client-specific formatting entirely. Using an **inline script** that runs synchronously as the browser parses the HTML, you can update the DOM **before the first paint**. This guide covers dates, themes, and persisted UI state. ## Example The companion [demo](https://preventing-flash-before-hydration.labs.vercel.dev/) ([source](https://github.com/vercel-labs/preventing-flash-before-hydration)) is built with `LANG=ja_JP.UTF-8` to simulate a server/client locale mismatch. It lets you compare: - Inline script date formatting with no flash and no hydration error - A Client Component that calls `toLocaleDateString()` directly, showing the hydration error - An accordion that persists its open section to `localStorage` using a lazy `useState` initializer Use Chrome DevTools [Sensors](https://developer.chrome.com/docs/devtools/sensors) to override your locale (e.g. `ru-RU`) and see how each approach behaves. ## Dates and formatting A UTC timestamp like `2026-06-15T18:00:00Z` represents a fixed point in time, but how it is formatted for display depends on the user's locale and timezone. `toLocaleDateString()` and `Intl.DateTimeFormat` on the server use the server's settings, which may not match the user's. ### The problem A natural approach is a Client Component that formats the date: ```tsx filename="app/components/event-date.tsx" switcher 'use client' export function EventDate({ date }: { date: string }) { return
{new Date(date).toLocaleDateString()}
} ``` ```jsx filename="app/components/event-date.js" switcher 'use client' export function EventDate({ date }) { return{new Date(date).toLocaleDateString()}
} ``` During SSR, `toLocaleDateString()` runs in Node.js and formats using the server's locale (e.g. `6/15/2026`). On hydration, React re-executes the component in the browser and produces the user's locale (e.g. `2026/6/15`). React detects the mismatch, throws a hydration error, and the user sees a flash. You could work around this with `useEffect` to update the date after hydration, but the user still sees the server-formatted date first. A Server Component avoids the error entirely, but the date is permanently in the server's locale. > **Good to know:** This issue is easy to miss in local development if your machine's locale matches your browser's. Run your dev server with `TZ` and `LANG` set differently from your browser to catch mismatches early (e.g. `TZ=UTC LANG=ja_JP.UTF-8 next dev`). `TZ=UTC` is a good default since most servers run in UTC. ### Fixing it with an inline script 1. The server renders the date with its locale into a ``. 2. Place a `