facebook/docusaurus · error · ReactContextError

Hook is called outside the <DocsSidebarProvider>.

Error message

Hook is called outside the <DocsSidebarProvider>. 

What it means

Thrown by useDocsSidebar() when the context value equals the EmptyContext sentinel, meaning no <DocsSidebarProvider> ancestor rendered. Unlike most provider hooks, useDocsSidebar legitimately returns null when a provider IS present but the current doc has no sidebar, so the sentinel specifically distinguishes 'provider missing' from 'provider present, no sidebar'. ReactContextError produces 'Hook useDocsSidebar is called outside the <DocsSidebarProvider>.'.

Source

Thrown at packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx:47

}: {
  children: ReactNode;
  name: string | undefined;
  items: PropSidebar | undefined;
}): ReactNode {
  const stableValue: ContextValue | null = useMemo(
    () => (name && items ? {name, items} : null),
    [name, items],
  );
  return <Context.Provider value={stableValue}>{children}</Context.Provider>;
}

/**
 * Gets the sidebar that's currently displayed, or `null` if there isn't one
 */
export function useDocsSidebar(): ContextValue | null {
  const value = useContext(Context);
  if (value === EmptyContext) {
    throw new ReactContextError('DocsSidebarProvider');
  }
  return value;
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Only call useDocsSidebar() within the DocsSidebarProvider subtree (the docs page layout).
  2. Remember the hook may still return null even with the provider — always null-check the return value for 'no sidebar on this doc'.
  3. Re-add DocsSidebarProvider in any swizzled docs layout.
  4. In tests, wrap renders in <DocsSidebarProvider name={...} items={...}>.

Example fix

// before
function Breadcrumbs() {
  const sidebar = useDocsSidebar(); // throws if no provider
}
// after: ensure provider wraps, and handle the null-sidebar case
const sidebar = useDocsSidebar();
if (!sidebar) return null;
Defensive patterns

Strategy: type-guard

Validate before calling

import {useDocsSidebar} from '@docusaurus/plugin-content-docs/client';

// useDocsSidebar() itself returns null when the provider exists but no sidebar;
// it only THROWS when the provider is missing. So guard at the call site by
// ensuring you are within the docs page subtree:
import useRouteContext from '@docusaurus/useRouteContext';
function useIsDocsPage() {
  return useRouteContext()?.plugin?.name === 'docusaurus-plugin-content-docs';
}
// if (!useIsDocsPage()) return null;
// const sidebar = useDocsSidebar(); if (!sidebar) return null;

Type guard

import type {Sidebars} from '@docusaurus/plugin-content-docs';

const hasSidebar = (sidebar: ReturnType<typeof useDocsSidebar>): boolean =>
  sidebar !== null && sidebar !== undefined;

Prevention

When it happens

Trigger: Calling useDocsSidebar() in a layout/navbar/footer rendered outside DocsSidebarProvider; swizzling the docs layout and removing the provider; using a sidebar-aware component on a non-doc route.

Common situations: Reusing sidebar breadcrumbs/components in a global layout; a swizzle of DocPage/Layout that dropped DocsSidebarProvider; importing a sidebar component into a custom page.

Related errors


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