ClientOnly
Renders its content only in the browser, after hydration, and a fallback on the server.
Client renders its children only in the browser, after hydration; on the server and during
hydration it renders fallback. Use it for content that differs between server and browser, such
as the reader's time zone or a browser API, so React does not report a hydration mismatch.
Your browser's time zone: -
// apps/docs/examples/ui/client-only.tsx'use client';
import {ClientOnly} from '@workspace/active-ui/components/composed/client-only';
/** * Reads browser APIs while it renders. As its own component it renders only * inside `ClientOnly`: an expression such as `{window.innerWidth}` written * directly as a child would run on the server too. */function BrowserFacts() { return ( <> <strong>{Intl.DateTimeFormat().resolvedOptions().timeZone}</strong>, window width {window.innerWidth} px </> );}
/** * Content that only the browser knows: your time zone and window width. The * server renders the fallback, and the browser replaces it after hydration, * without a mismatch. */export default function ClientOnlyExample() { return ( <p className="text-sm"> Your browser's time zone:{' '} <ClientOnly fallback={<span className="text-muted-foreground">-</span>}> <BrowserFacts /> </ClientOnly> </p> );}What the composition adds#
It uses use, built on use: false on the
server and during hydration, true after it.
The children run on the server too#
React evaluates the children where Client is written, before Client decides what to
render. An expression such as {window. as a child therefore runs on the server and
fails there. Put code that reads a browser API in a component of its own, as Browser in the
example, and render that component inside Client.
Usage#
import {ClientOnly} from '@workspace/active-ui/components/composed/client-only';
<ClientOnly fallback="-">{formatDateTime(createdAt, presentation)}</ClientOnly>;What your application provides#
A fallback with the same size as the content where a jump in the layout would disturb.
Content that can render on the server stays outside: everything inside appears only after hydration, and search engines and readers without JavaScript see the fallback.