Describe the bug
docusaurus-theme-openapi-docs v4.7.1 is incompatible with @docusaurus/core 3.10.0 due to a breaking change in the internal Tabs API introduced in facebook/docusaurus#11733.
The build fails with SSG errors on all pages that use the theme's tab components:
Error: useTabsContext() must be used within a Tabs component
In Docusaurus 3.10.0, the Tabs system was refactored to use React context:
- Before (<=3.9.x): useTabs(props: TabsProps) accepted props and returned tab state. TabItem received hidden via cloneElement().
- After (3.10.0): useTabs() takes no arguments and reads from a new TabsContext via TabsProvider. TabItem self-manages visibility via context. The old behavior is now available as useTabsContextValue(props).
All four custom tab components in this theme call useTabs(props) with the old signature:
- src/theme/ApiTabs/index.tsx (line ~223)
- src/theme/SchemaTabs/index.tsx (line ~218)
- src/theme/MimeTabs/index.tsx (line ~237)
- src/theme/OperationTabs/index.tsx (line ~200)
Each follows this pattern:
import {
sanitizeTabsChildren,
TabProps,
useScrollPositionBlocker,
useTabs,
} from "@docusaurus/theme-common/internal";
function TabsComponent(props: TabListProps): React.JSX.Element {
const tabs = useTabs(props); // ← breaks in 3.10.0
return (
<div className="openapi-tabs__container">
<TabList {...props} {...tabs} />
<TabContent {...props} {...tabs} />
</div>
);
}
Possible solution
To support Docusaurus 3.10.0, each component needs to:
- Replace useTabs(props) with useTabsContextValue(props) (the renamed version that accepts props)
- Wrap children in so that TabItem can read from context
- Remove cloneElement-based hidden prop injection in TabContent, since TabItem now self-manages visibility via useTabs() context
The new pattern would look roughly like:
import {
sanitizeTabsChildren,
TabProps,
useScrollPositionBlocker,
useTabsContextValue, // renamed from useTabs
TabsProvider, // new context provider
} from "@docusaurus/theme-common/internal";
function TabsComponent(props: TabListProps): React.JSX.Element {
const tabs = useTabsContextValue(props);
return (
<TabsProvider value={tabs}>
<div className="openapi-tabs__container">
<TabList {...props} {...tabs} />
<TabContent {...props} {...tabs} />
</div>
</TabsProvider>
);
}
TabContent would also need updating — it currently uses cloneElement to inject hidden into children, but TabItem in 3.10.0 determines its own visibility from context.
Steps to reproduce
- Install
[email protected] with @docusaurus/[email protected]
- Generate API docs from any OpenAPI spec
- Run
docusaurus build
- Build fails with
useTabsContext() must be used within a Tabs component for every API page
Disclaimer
A lot of the information in the description was generated by Claude while trying to debug my issue.
Describe the bug
docusaurus-theme-openapi-docsv4.7.1 is incompatible with@docusaurus/core3.10.0 due to a breaking change in the internal Tabs API introduced in facebook/docusaurus#11733.The build fails with SSG errors on all pages that use the theme's tab components:
Error: useTabsContext() must be used within a Tabs componentIn Docusaurus 3.10.0, the Tabs system was refactored to use React context:
All four custom tab components in this theme call useTabs(props) with the old signature:
Each follows this pattern:
Possible solution
To support Docusaurus 3.10.0, each component needs to:
The new pattern would look roughly like:
TabContent would also need updating — it currently uses cloneElement to inject hidden into children, but TabItem in 3.10.0 determines its own visibility from context.
Steps to reproduce
[email protected]with@docusaurus/[email protected]docusaurus builduseTabsContext() must be used within a Tabs componentfor every API pageDisclaimer
A lot of the information in the description was generated by Claude while trying to debug my issue.