facebook/docusaurus · error · ReactContextError
Hook ${hookName} is called outside the <TitleFormatterProvid
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.
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)
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
- Hook is called outside the <AnnouncementBarProvider>.
- Hook is called outside the <ColorModeProvider>. Please see h
- Hook is called outside the <NavbarMobileSidebarProvider>.
- Hook is called outside the <NavbarSecondaryMenuContentProvid
- Hook is called outside the <NavbarSecondaryMenuDisplayProvid
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/83d623f00150aced.
Report an issue: GitHub.