facebook/docusaurus · error · ReactContextError
Hook is called outside the .
Error message
Hook ${hookName} is called outside the <TitleFormatterProvider>. What it means
useTitleFormatter() reads TitleFormatterContext via useTitleFormatterContext; when the context value is null (no TitleFormatterProvider ancestor), it throws a ReactContextError. The hook name in the message is parsed from the call stack, so the same generic error reports whichever consuming hook (useTitleFormatter, useTitleFormatterContext) was invoked outside the provider.
Solutions
- Keep the default theme provider chain intact so TitleFormatterProvider wraps the router.
- If you swizzle the root, re-add <TitleFormatterProvider formatter={...}> around your tree (use the default formatter from TitleFormatterFnDefault).
- Only call useTitleFormatter() from components rendered within a routed page.
Example fix
// before (custom root, provider removed)
export default function Root({children}) {
return <>{children}</>;
}
// after
import {TitleFormatterProvider, TitleFormatterFnDefault} from '@docusaurus/theme-common/internal';
export default function Root({children}) {
return (
<TitleFormatterProvider formatter={TitleFormatterFnDefault}>
{children}
</TitleFormatterProvider>
);
} Defensive patterns
Strategy: type-guard
Prevention
- Do not remove TitleFormatterProvider when swizzling the root/layout.
- Only call useTitleFormatter() from components inside the routed page tree.
- When customizing the formatter, replace the provider value rather than deleting the provider.
When it happens
Trigger: Call useTitleFormatter() in a component rendered above TitleFormatterProvider; customize the theme root layout and omit or reorder the provider; call the hook in a context that is not a route child (provider is applied within the router tree).
Common situations: Swizzle/customize ThemeRoot or Layout and drop TitleFormatterProvider; using the hook in a top-level provider that sits above where Docusaurus injects it; calling the formatter outside React render (it is a hook).
Related errors
- Can't select invalid tab value=
- Hook is called outside the
- Hook is called outside the
- Hook is called outside the
- Hook is called outside the
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/83d623f00150aced.
Report an issue: GitHub.
Appendix: source
Thrown at packages/docusaurus-theme-common/src/utils/titleFormatterUtils.tsx:95
export function TitleFormatterProvider({
formatter,
children,
}: {
children: ReactNode;
formatter: TitleFormatterFnWithDefault;
}): ReactNode {
return (
<TitleFormatterContext.Provider value={formatter}>
{children}
</TitleFormatterContext.Provider>
);
}
function useTitleFormatterContext() {
const value = useContext(TitleFormatterContext);
if (value === null) {
throw new ReactContextError('TitleFormatterProvider');
}
return value;
}
/**
* Returns a function to format the page title
*/
export function useTitleFormatter(): TitleFormatter {
const formatter = useTitleFormatterContext();
const {siteConfig} = useDocusaurusContext();
const {title: siteTitle, titleDelimiter} = siteConfig;
// Unfortunately we can only call this hook here, not in the provider
// Route context can't be accessed in any provider applied above the router
const {plugin} = useRouteContext();
return {
format: (title: string) =>View on GitHub (pinned to 3f483e80e3)