shadcn.io is an independent project built on shadcn/ui
useIsClient is false on the server and on the first client render, then true after hydration.
Use that boolean before you read window, document, or localStorage, or before you render something that only exists in the browser. For a layout read that must happen before paint, use useIsomorphicLayoutEffect. React renders the server HTML and the first client pass the same, so the two stay in sync.
Installation
Anatomy

Usage
import { useIsClient } from "@/hooks/use-is-client";const isClient = useIsClient();Branch the tree on isClient when the client version would touch window or document. Both the server and the first client render see false.
FAQ
How does useIsClient avoid a hydration mismatch?
It starts as false and only becomes true in an effect. The server render and the first client render both see false, so the HTML matches. After hydration the effect sets it to true and React renders again. If you instead branch on typeof window during render, the server and the client can disagree and React warns. Keep the branch on the boolean this hook returns.
Why not check typeof window myself?
A typeof window check is fine inside an effect or an event handler, where only the client runs it. It is a problem during render if the two environments return different JSX. useIsClient stays false for the render that must match the server, then flips. Use the hook when the branch is in the tree. Use a direct check when the code cannot run on the server at all.
When can I read window or document?
Read them when useIsClient has returned true, or inside an effect, which already runs only on the client. A guard like if (isClient) around a click handler is optional, because the click itself only happens in the browser. You need the guard when the render path would touch window, document, localStorage, or navigator while the boolean is still false.
Why not only use useEffect for client code?
useEffect is the right place for a side effect, and it already skips the server. It does not let you return different JSX for the client without a separate piece of state. useIsClient is that piece of state. It is false, then true, and your render can branch on it. You still put subscriptions and other work in effects.
Does useIsClient cause an extra render?
Yes, one. The component renders with false, the effect runs, and it renders again with true. That second render is what makes the server HTML and the first client render match. It does not subscribe to anything and it does not update again after that. If the client-only tree is large, keep it small so the extra render stays cheap.
What should I show before the flag becomes true?
Show the same thing you are willing to send from the server. A short placeholder, an empty box, or the non-browser version of the control all work. Do not read window while building that first tree. After the flag flips, render the client version. People may notice one update. That is the trade for HTML that hydrates cleanly.
API Reference
Returns
returnsboolean
true once mounted in the browser.











