{"record":{"id":"d59a41aba0001b0e","repo":"facebook/docusaurus","slug":"hook-is-called-outside-the-docssidebarprovider","errorCode":null,"errorMessage":"Hook is called outside the <DocsSidebarProvider>. ","messagePattern":"Hook is called outside the <DocsSidebarProvider>\\. ","errorType":"exception","errorClass":"ReactContextError","httpStatus":null,"severity":"error","filePath":"packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx","lineNumber":47,"sourceCode":"}: {\n  children: ReactNode;\n  name: string | undefined;\n  items: PropSidebar | undefined;\n}): ReactNode {\n  const stableValue: ContextValue | null = useMemo(\n    () => (name && items ? {name, items} : null),\n    [name, items],\n  );\n  return <Context.Provider value={stableValue}>{children}</Context.Provider>;\n}\n\n/**\n * Gets the sidebar that's currently displayed, or `null` if there isn't one\n */\nexport function useDocsSidebar(): ContextValue | null {\n  const value = useContext(Context);\n  if (value === EmptyContext) {\n    throw new ReactContextError('DocsSidebarProvider');\n  }\n  return value;\n}\n","sourceCodeStart":29,"sourceCodeEnd":51,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus-plugin-content-docs/src/client/docsSidebar.tsx#L29-L51","documentation":"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>.'.","triggerScenarios":"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.","commonSituations":"Reusing sidebar breadcrumbs/components in a global layout; a swizzle of DocPage/Layout that dropped DocsSidebarProvider; importing a sidebar component into a custom page.","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={...}>."],"exampleFix":"// before\nfunction Breadcrumbs() {\n  const sidebar = useDocsSidebar(); // throws if no provider\n}\n// after: ensure provider wraps, and handle the null-sidebar case\nconst sidebar = useDocsSidebar();\nif (!sidebar) return null;","handlingStrategy":"type-guard","validationCode":"import {useDocsSidebar} from '@docusaurus/plugin-content-docs/client';\n\n// useDocsSidebar() itself returns null when the provider exists but no sidebar;\n// it only THROWS when the provider is missing. So guard at the call site by\n// ensuring you are within the docs page subtree:\nimport useRouteContext from '@docusaurus/useRouteContext';\nfunction useIsDocsPage() {\n  return useRouteContext()?.plugin?.name === 'docusaurus-plugin-content-docs';\n}\n// if (!useIsDocsPage()) return null;\n// const sidebar = useDocsSidebar(); if (!sidebar) return null;","typeGuard":"import type {Sidebars} from '@docusaurus/plugin-content-docs';\n\nconst hasSidebar = (sidebar: ReturnType<typeof useDocsSidebar>): boolean =>\n  sidebar !== null && sidebar !== undefined;","tryCatchPattern":null,"preventionTips":["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."],"tags":["react-hook","docs","sidebar","react-context","swizzle"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}