facebook/docusaurus · error · Error

Docusaurus error: The children of <BrowserOnly> must be a "r

Error message

Docusaurus error: The children of <BrowserOnly> must be a "render function", e.g. <BrowserOnly>{() => <span>{window.location.href}</span>}</BrowserOnly>.
Current type: ${isValidElement(children) ? 'React element' : typeof children}

What it means

<BrowserOnly> defers rendering to the browser by invoking its children as a function. The component checks typeof children === 'function' only in development (NODE_ENV === 'development') and throws when children is anything else (a JSX element, a variable, etc.). The message tells you the received type. Pass a render function: <BrowserOnly>{() => <span>{window.location.href}</span>}</BrowserOnly>.

Source

Thrown at packages/docusaurus/src/client/exports/BrowserOnly.tsx:22

 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import React, {isValidElement, type ReactNode} from 'react';
import useIsBrowser from '@docusaurus/useIsBrowser';
import type {Props} from '@docusaurus/BrowserOnly';

// Similar comp to the one described here:
// https://www.joshwcomeau.com/react/the-perils-of-rehydration/#abstractions
export default function BrowserOnly({children, fallback}: Props): ReactNode {
  const isBrowser = useIsBrowser();

  if (isBrowser) {
    if (
      typeof children !== 'function' &&
      process.env.NODE_ENV === 'development'
    ) {
      throw new Error(`Docusaurus error: The children of <BrowserOnly> must be a "render function", e.g. <BrowserOnly>{() => <span>{window.location.href}</span>}</BrowserOnly>.
Current type: ${isValidElement(children) ? 'React element' : typeof children}`);
    }
    return <>{children?.()}</>;
  }

  return fallback ?? null;
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Wrap children in an arrow function: <BrowserOnly>{() => <YourComponent />}</BrowserOnly>.
  2. If you pass a variable, pass a closure: <BrowserOnly>{() => node}</BrowserOnly>.
  3. Note the check fires only in dev; production silently calls children?.() and renders nothing for non-functions, so fix it before shipping.

Example fix

// before
<BrowserOnly>
  <span>{window.location.href}</span>
</BrowserOnly>
// after
<BrowserOnly>
  {() => <span>{window.location.href}</span>}
</BrowserOnly>
Defensive patterns

Strategy: validation

Validate before calling

function assertBrowserOnlyChildren(children: unknown) {
  if (typeof children !== 'function') {
    throw new Error(
      '<BrowserOnly> children must be a render function: () => ReactNode',
    );
  }
}

Type guard

const isRenderFunction = (
  c: unknown,
): c is () => React.ReactNode => typeof c === 'function';

Prevention

When it happens

Trigger: Write <BrowserOnly><span>{window.location.href}</span></BrowserOnly> (element, not function); pass a pre-built element variable as children; refactor that drops the arrow wrapper.

Common situations: First use of BrowserOnly; converting a regular component to BrowserOnly without wrapping children in an arrow function; copy-paste from non-BrowserOnly patterns.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/7ac10d1cee91187c. Report an issue: GitHub.