Skip to content
On this page

SSR and RSC

The server can render useful markup, but it cannot know a visitor's viewport, clipboard, connection, or storage. Better Hooks keeps that gap visible instead of guessing.

Put the boundary beside the Hook

A Better Hook must run in a Client Component. Put 'use client' in the smallest component that calls it. A Server Component can render that child and pass serializable props, but it cannot call the Hook itself.

Importing is safe; calling is client work

Importing the package does not register listeners, start timers, read storage, or touch the DOM. That makes an import safe in a server build. Calling the Hook still belongs in the client tree.

Start with a steady fallback

Browser-facing Hooks return a documented server value:

HookServer result
useMediaQuerydefaultMatches, otherwise false
useWindowSize{ width: 0, height: 0 }
useOnlinetrue
storage Hooksthe initial value you provide
listener and timer Hooksno subscription or timer during server rendering

Choose an explicit initial value when the neutral default is not right for your UI.

Let hydration fill in the browser value

Render a useful first frame, then let React reconcile the live browser snapshot after hydration. Avoid replacing a large part of the page only because a measurement was unknown on the server.

Treat missing browser APIs as normal

A browser API may be unavailable or may reject access. Each Hook either returns its documented fallback or exposes the error. Keep a neutral UI available instead of assuming the capability is always present.