browser

browser lets you mark a component as browser-only during server rendering.

use(browser(reason?))

Reference

browser(reason?)

Call browser inside use to mark a component as browser-only during server rendering:

import { use } from 'react';
import { browser } from 'react-dom';

function BrowserOnly() {
use(browser('This component requires browser APIs.'));
return <BrowserContent />;
}

During server rendering, use(browser()) stops rendering the component and leaves the closest <Suspense> boundary’s fallback in its place. In the browser, use(browser()) returns undefined, so the component renders normally.

See more examples below.

Parameters

  • optional reason: A string or function that explains why the content needs to render in the browser. The string or the function’s return value becomes the cause of the Error passed to onBrowserBailout. React calls a reason function each time a server renderer encounters the value returned by browser, but does not call it in the browser. If creating the reason is expensive, pass a function such as () => new Error(...).

Returns

browser returns an opaque value that you can pass to use in a component or use as the reason when aborting a server render. In the browser, passing this value to use returns undefined.

Caveats

  • use(browser()) must be inside a <Suspense> boundary during server rendering. Without one, the server render fails.
  • use(browser()) must be called from a Client Component, not a Server Component.
  • Calling browser() by itself has no effect. To mark a component as browser-only, pass the value returned by browser to use. Do not throw it.

Usage

Rendering content only in the browser

Call browser inside use in a component that should only render in the browser:

You can use this instead of checking typeof window, waiting for an Effect to set mounted state, or using a framework option to disable server rendering.

Click Reload to see the loading fallback in the initial HTML. After hydration, React displays the draft loaded from localStorage.

import { Suspense, use, useState } from 'react';
import { browser } from 'react-dom';

function SavedDraft() {
  use(browser('The draft is stored in localStorage.'));
  const [draft, setDraft] = useState(
    () => localStorage.getItem('draft') ?? ''
  );

  function handleChange(event) {
    const nextDraft = event.target.value;
    setDraft(nextDraft);
    localStorage.setItem('draft', nextDraft);
  }

  return (
    <label>
      Draft:
      <textarea
        value={draft}
        onChange={handleChange}
        rows={4}
        cols={30}
      />
    </label>
  );
}

export default function App() {
  return (
    <>
      <h1>Saved draft</h1>
      <Suspense fallback={<p>Loading draft...