facebook/docusaurus · error · Error
useBlogMetadata() can't be called on the current route becau
Error message
useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context
What it means
Thrown by useBlogMetadata() when useRouteContext() returns a route whose data does not carry a `blogMetadata` field. Blog metadata is injected onto the blog list route's route context by the blog plugin; calling this hook on a route that is not the blog list (e.g. a blog post page, a non-blog page, or during SSR outside the routed tree) yields no blogMetadata and throws. Unlike the provider-based hooks, this one reads from the route context, not a React Context provider.
Source
Thrown at packages/docusaurus-plugin-content-blog/src/client/contexts.tsx:21
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, {useMemo, type ReactNode, useContext} from 'react';
import {ReactContextError} from '@docusaurus/theme-common';
import useRouteContext from '@docusaurus/useRouteContext';
import type {
PropBlogPostContent,
BlogMetadata,
} from '@docusaurus/plugin-content-blog';
export function useBlogMetadata(): BlogMetadata {
const routeContext = useRouteContext();
const blogMetadata = routeContext?.data?.blogMetadata;
if (!blogMetadata) {
throw new Error(
"useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context",
);
}
return blogMetadata as BlogMetadata;
}
/**
* The React context value returned by the `useBlogPost()` hook.
* It contains useful data related to the currently browsed blog post.
*/
export type BlogPostContextValue = Pick<
PropBlogPostContent,
'metadata' | 'frontMatter' | 'assets' | 'toc'
> & {
readonly isBlogPostPage: boolean;
};
const Context = React.createContext<BlogPostContextValue | null>(null);View on GitHub (pinned to 3f483e80e3)
Solutions
- Only call useBlogMetadata() within components rendered under the blog list route (the BlogListPage theme component and its descendants).
- If the component must render on multiple route types, first check the route context / page type before calling the hook.
- For blog-post-specific data, use useBlogPost() instead (which reads from BlogPostProvider).
- Confirm you are not accidentally rendering the component during SSR or in a storybook/preview without the route wiring.
Example fix
// before
function MyComponent() {
const meta = useBlogMetadata(); // throws on non-list routes
return <span>{meta.blogTitle}</span>;
}
// after: guard by route, or move into BlogListPage subtree only
function MyComponent() {
const routeContext = useRouteContext();
if (!routeContext?.data?.blogMetadata) return null;
const meta = useBlogMetadata();
return <span>{meta.blogTitle}</span>;
} Defensive patterns
Strategy: validation
Validate before calling
import useRouteContext from '@docusaurus/useRouteContext';
function useIsBlogListRoute() {
const routeContext = useRouteContext();
return Boolean(routeContext?.data?.blogMetadata);
}
// if (!useIsBlogListRoute()) return null; // before calling useBlogMetadata() Type guard
const hasBlogMetadata = ( routeContext: ReturnType<typeof useRouteContext>, ): boolean => Boolean(routeContext?.data?.blogMetadata);
Prevention
- Restrict useBlogMetadata() to BlogListPage and its descendants only.
- For shared components, check routeContext.data.blogMetadata before calling.
- Use useBlogPost() for blog-post-page data, not useBlogMetadata().
When it happens
Trigger: Calling useBlogMetadata() inside a component rendered on a blog post page (which uses BlogPostProvider, not the list route), on a docs/page route, or in a theme layout component that renders on every page regardless of route type.
Common situations: Swizzling a shared layout/navbar component and dropping useBlogMetadata() in without guarding the route type; copying blog-list code into a blog post template; using the hook in a component that also renders on the homepage.
Related errors
- Hook is called outside the <BlogPostProvider>.
- Hook is called outside the <DocProvider>.
- Hook is called outside the <DocSidebarItemsExpandedStateProv
- Hook is called outside the <DocsPreferredVersionContextProvi
- Hook is called outside the <DocsSidebarProvider>.
AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12).
Data as JSON: /api/errors/d18224d1da4d3956.
Report an issue: GitHub.