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
- Only call useDocsSidebar() within the DocsSidebarProvider subtree (the docs page layout).
- Remember the hook may still return null even with the provider — always null-check the return value for 'no sidebar on this doc'.
- Re-add DocsSidebarProvider in any swizzled docs layout.
- 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
- Always null-check useDocsSidebar() return even when the provider is present.
- Keep DocsSidebarProvider in the swizzled docs layout.
- Use useRouteContext() to gate sidebar hooks to docs routes.
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
- Hook is called outside the <DocSidebarItemsExpandedStateProv
- Hook is called outside the <DocProvider>.
- Hook is called outside the <DocsPreferredVersionContextProvi
- Hook is called outside the <DocsVersionProvider>.
- Hook is called outside the <BlogPostProvider>.
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/d59a41aba0001b0e.
Report an issue: GitHub.