facebook/docusaurus · error · Error
useTabsContext() must be used within a Tabs component
Error message
useTabsContext() must be used within a Tabs component
What it means
useTabs() reads the TabsContext created by <Tabs>/TabsProvider. React.useContext returns null when the hook is called from a component that is not a descendant of a TabsProvider, and the guard throws 'useTabsContext() must be used within a Tabs component'. This is the standard React 'missing provider' failure.
Source
Thrown at packages/docusaurus-theme-common/src/utils/tabsUtils.tsx:297
},
[setQueryString, setStorageValue, tabValues],
);
return {
selectedValue,
selectValue,
tabValues,
lazy: props.lazy ?? false,
block: props.block ?? false,
};
}
const TabsContext = createContext<TabsContextValue | null>(null);
export function useTabs(): TabsContextValue {
const contextValue = React.useContext(TabsContext);
if (!contextValue) {
throw new Error('useTabsContext() must be used within a Tabs component');
}
return contextValue;
}
export function TabsProvider(props: {
children: ReactNode;
value: TabsContextValue;
}): ReactNode {
return (
<TabsContext.Provider value={props.value}>
{props.children}
</TabsContext.Provider>
);
}
View on GitHub (pinned to 3f483e80e3)
Solutions
- Move the component calling useTabs() to be a descendant of <Tabs>.
- In tests, render the consumer inside <TabsProvider value={...}> or a real <Tabs>.
- Pass the needed value via props instead of context if the component must live outside the Tabs tree.
Example fix
// before
function TabLabel() {
const {selectedValue} = useTabs(); // rendered outside <Tabs>
return <b>{selectedValue}</b>;
}
<TabLabel />
<Tabs>...</Tabs>
// after
<Tabs>
<TabLabel />
</Tabs> Defensive patterns
Strategy: type-guard
Try / catch
// In a custom hook used in non-Tabs contexts
import {useTabs} from '@docusaurus/theme-common/internal';
function useTabsOptional() {
try {
return useTabs();
} catch {
return null; // caller falls back to props
}
} Prevention
- Keep useTabs consumers physically nested inside <Tabs> in JSX.
- In tests, wrap the consumer in <Tabs> or <TabsProvider value={...}>.
- Prefer passing data via props when a component must render outside Tabs.
When it happens
Trigger: Call useTabs() in a component rendered outside <Tabs>; use it in a unit test without wrapping in TabsProvider; lift a TabItem-child component above the <Tabs> boundary during refactor.
Common situations: Extracting an inline child into a standalone component placed at the wrong level; RTL/Jest tests of a tab-aware component without the provider; reordering JSX so the consumer renders before/above <Tabs>.
Related errors
- Can't select invalid tab value=${newValue}
- usePlayground must be used within PlaygroundProvider
- Hook is called outside the <AnnouncementBarProvider>.
- Hook is called outside the <ColorModeProvider>. Please see h
- Hook is called outside the <NavbarMobileSidebarProvider>.
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/d5ec668a5e971c13.
Report an issue: GitHub.