facebook/docusaurus · error · ReactContextError
Hook is called outside the <DocsPreferredVersionContextProvi
Error message
Hook is called outside the <DocsPreferredVersionContextProvider>.
What it means
Thrown by useDocsPreferredVersionContext() when the context value is falsy, i.e. no <DocsPreferredVersionContextProvider> ancestor. This provider (the safe wrapper DocsPreferredVersionContextProvider around the unsafe variant) persists the user's last-visited version per plugin id. ReactContextError yields 'Hook useDocsPreferredVersionContext is called outside the <DocsPreferredVersionContextProvider>.'. Note the guard here is `if (!value)` rather than a sentinel.
Source
Thrown at packages/docusaurus-plugin-content-docs/src/client/docsPreferredVersion.tsx:187
* This is a maybe-layer. If the docs plugin is not enabled, this provider is a
* simple pass-through.
*/
export function DocsPreferredVersionContextProvider({
children,
}: {
children: ReactNode;
}): ReactNode {
return (
<DocsPreferredVersionContextProviderUnsafe>
{children}
</DocsPreferredVersionContextProviderUnsafe>
);
}
function useDocsPreferredVersionContext(): ContextValue {
const value = useContext(Context);
if (!value) {
throw new ReactContextError('DocsPreferredVersionContextProvider');
}
return value;
}
/**
* Returns a read-write interface to a plugin's preferred version. The
* "preferred version" is defined as the last version that the user visited.
* For example, if a user is using v3, even when v4 is later published, the user
* would still be browsing v3 docs when she opens the website next time. Note,
* the `preferredVersion` attribute will always be `null` before mount.
*/
export function useDocsPreferredVersion(
pluginId: string | undefined = DEFAULT_PLUGIN_ID,
): {
preferredVersion: GlobalVersion | null;
savePreferredVersionName: (versionName: string) => void;
} {
const docsData = useDocsData(pluginId);View on GitHub (pinned to 3f483e80e3)
Solutions
- Ensure <DocsPreferredVersionContextProvider> remains in the root layout (Docusaurus wires it via the theme's providers; keep it when swizzling Root).
- Only call useDocsPreferredVersion() under that provider subtree.
- In tests, wrap renders in DocsPreferredVersionContextProvider.
- If the component is used outside versioned contexts, gate the call behind a route/version check.
Example fix
// before: swizzled Root dropped the provider
const Root = ({children}) => <>{children}</>;
// after: keep the provider in the provider chain
const Root = ({children}) => (
<DocsPreferredVersionContextProvider>
{children}
</DocsPreferredVersionContextProvider>
); Defensive patterns
Strategy: validation
Validate before calling
import {useContext} from 'react';
import {DocsPreferredVersionContext} from '@docusaurus/plugin-content-docs/client';
function useHasPreferredVersionProvider() {
return useContext(DocsPreferredVersionContext) != null;
}
// (export the context or use the provider's presence structurally) Prevention
- Never remove DocsPreferredVersionContextProvider from the swizzled Root layout.
- Only call useDocsPreferredVersion() on doc/versioned routes.
- In tests, wrap renders in DocsPreferredVersionContextProvider.
When it happens
Trigger: Calling useDocsPreferredVersion() outside the provider tree; swizzling the root layout and dropping DocsPreferredVersionContextProvider; rendering a version-aware component on a page not under the provider.
Common situations: Customizing the root Theme/Layout and removing the provider that Docusaurus wires into it; reusing a version-switcher component in a context where the provider was never mounted; partial swizzle that kept the unsafe provider but removed the safe wrapper.
Related errors
- Hook is called outside the <DocsVersionProvider>.
- Hook is called outside the <DocProvider>.
- Hook is called outside the <DocSidebarItemsExpandedStateProv
- Hook is called outside the <DocsSidebarProvider>.
- Hook is called outside the <BlogPostProvider>.
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/77b1f4d7d0593429.
Report an issue: GitHub.