useMounted
A hook that reports whether the component has mounted on the client.
The server has no timezone for this user, so the formatted time renders only after hydration.
Installation
Usage
For the handful of values that genuinely cannot match between server and client — a locale-formatted
date, a resolved theme, a portal target, anything read from window — render a stable placeholder
until after hydration.
import { useMounted } from "@/hooks/use-mounted";
function LocalTime({ date }: { date: Date }) {
const mounted = useMounted();
if (!mounted) return <span className="opacity-0">00:00</span>;
return <span>{date.toLocaleTimeString()}</span>;
}Why useSyncExternalStore
The usual implementation is useState(false) plus an effect that sets it to true. That works, but
it schedules an extra state update on every mounted component and is easy to accidentally call
during a render that React may discard.
useSyncExternalStore expresses the same thing declaratively: the server snapshot is false, the
client snapshot is true, and the store never notifies. React reads false while rendering on the
server and during hydration, then true — no effect, no extra state.
Use it sparingly
Every useMounted branch is content the user does not see on first paint, and it is not the fix for
most hydration warnings. Reach for it when the value is genuinely client-only. When the difference
is only visual, prefer CSS; when it is data, prefer passing it down from the server.