ClientOnly

Some components depend on browser APIs such as window.innerWidth, localStorage, or navigator, or on third-party libraries that access the DOM. These APIs are not available on the server, so those components cannot be rendered during Static Site Generation.

<ClientOnly> skips its children during server rendering and renders them in the browser.

Usage

import { ClientOnly } from 'retend-server';

function App() {
  return (
    <div>
      <h1>My Page</h1>

      <ClientOnly fallback={<p>Loading interactive content...</p>}>
        <BrowserOnlyWidget />
      </ClientOnly>
    </div>
  );
}

During SSG, fallback is rendered instead. After the JavaScript loads and the component mounts in the browser, the children replace the fallback.

ClientReady

Use <ClientReady> when a browser-only subtree performs asynchronous work that must finish before the fallback is removed. Like <ClientOnly>, it skips the subtree during SSG, then keeps the fallback visible until the subtree mounts and its initial <Await> boundary resolves.

import { ClientReady } from 'retend-server';

function App() {
  return (
    <ClientReady fallback={<BootScreen />}>
      <Dashboard />
    </ClientReady>
  );
}

This is appropriate for app shells, boot screens, and browser-only dashboards that should not display the client subtree before its initial asynchronous work is ready.

When to Use It

Use <ClientOnly> when a component:

  • Reads from window, document, or navigator.
  • Uses localStorage or sessionStorage.
  • Depends on a third-party library that accesses the DOM at import time.
  • Measures element dimensions or positions.

Components that do not use browser APIs do not need <ClientOnly>; Retend's SSG can render them normally.

Without a Fallback

To omit placeholder content, leave out the fallback prop. The area is empty during server rendering and appears when the client hydrates:

<ClientOnly>
  <InteractiveMap />
</ClientOnly>