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
- Wrap children in an arrow function: <BrowserOnly>{() => <YourComponent />}</BrowserOnly>.
- If you pass a variable, pass a closure: <BrowserOnly>{() => node}</BrowserOnly>.
- 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
- Always write <BrowserOnly>{() => ...}</BrowserOnly>; the arrow is not optional.
- Add an ESLint rule or review checklist catching <BrowserOnly> without a function child.
- Remember the dev-only throw means CI/dev will catch it, but production silently no-ops.
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
- Docusaurus plugin global data not found for "${pluginName}"
- Docusaurus plugin global data not found for "${pluginName}"
- Docusaurus static site generation failed for ${ssgErrors.len
- Docusaurus Bug: server bundle export from "${filename}" must
- Wrong icon: ${icon}
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/7ac10d1cee91187c.
Report an issue: GitHub.