diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json
index 81b398107e59..e01d774d0b91 100644
--- a/packages/docusaurus-plugin-content-blog/package.json
+++ b/packages/docusaurus-plugin-content-blog/package.json
@@ -4,9 +4,21 @@
"description": "Blog plugin for Docusaurus.",
"main": "lib/index.js",
"types": "src/plugin-content-blog.d.ts",
+ "exports": {
+ "./lib/*": "./lib/*",
+ "./src/*": "./src/*",
+ "./client": {
+ "type": "./lib/client/index.d.ts",
+ "default": "./lib/client/index.js"
+ },
+ ".": {
+ "types": "./src/plugin-content-blog.d.ts",
+ "default": "./lib/index.js"
+ }
+ },
"scripts": {
- "build": "tsc",
- "watch": "tsc --watch",
+ "build": "tsc --build",
+ "watch": "tsc --build --watch",
"test:generate-build-snap": "yarn docusaurus build src/__tests__/__fixtures__/website --out-dir build-snap && yarn rimraf src/__tests__/__fixtures__/website/.docusaurus && yarn rimraf src/__tests__/__fixtures__/website/build-snap/assets && git add src/__tests__/__fixtures__/website/build-snap"
},
"repository": {
diff --git a/packages/docusaurus-plugin-content-blog/src/client/index.ts b/packages/docusaurus-plugin-content-blog/src/client/index.ts
new file mode 100644
index 000000000000..333ddc5a4d7b
--- /dev/null
+++ b/packages/docusaurus-plugin-content-blog/src/client/index.ts
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import useRouteContext from '@docusaurus/useRouteContext';
+import type {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;
+}
diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts
index bf7f72d71b6e..75f6edf0a3d0 100644
--- a/packages/docusaurus-plugin-content-blog/src/index.ts
+++ b/packages/docusaurus-plugin-content-blog/src/index.ts
@@ -42,6 +42,7 @@ import type {
BlogTags,
BlogContent,
BlogPaginated,
+ BlogMetadata,
} from '@docusaurus/plugin-content-blog';
export default async function pluginContentBlog(
@@ -262,7 +263,7 @@ export default async function pluginContentBlog(
{
blogBasePath: normalizeUrl([baseUrl, routeBasePath]),
blogTitle,
- },
+ } satisfies BlogMetadata,
null,
2,
),
@@ -286,6 +287,8 @@ export default async function pluginContentBlog(
modules: {
sidebar: aliasedSource(sidebarProp),
content: metadata.source,
+ },
+ context: {
blogMetadata: aliasedSource(blogMetadataPath),
},
});
diff --git a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts
index a245fbcbd901..2a37d67dfe54 100644
--- a/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts
+++ b/packages/docusaurus-plugin-content-blog/src/plugin-content-blog.d.ts
@@ -5,6 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/
+///
+
declare module '@docusaurus/plugin-content-blog' {
import type {LoadedMDXContent} from '@docusaurus/mdx-loader';
import type {MDXOptions} from '@docusaurus/mdx-loader';
@@ -563,25 +565,7 @@ declare module '@theme/BlogPostPage/Metadata' {
}
declare module '@theme/BlogPostPage/StructuredData' {
- import type {
- BlogPostFrontMatter,
- PropBlogPostContent,
- BlogMetadata,
- } from '@docusaurus/plugin-content-blog';
-
- export type FrontMatter = BlogPostFrontMatter;
-
- export type Assets = PropBlogPostContent['assets'];
-
- export type Metadata = PropBlogPostContent['metadata'];
-
- export interface Props {
- readonly assets: Assets;
- readonly metadata: Metadata;
- readonly blogMetadata: BlogMetadata;
- }
-
- export default function BlogPostStructuredData(props: Props): JSX.Element;
+ export default function BlogPostStructuredData(): JSX.Element;
}
declare module '@theme/BlogListPage' {
diff --git a/packages/docusaurus-plugin-content-blog/tsconfig.client.json b/packages/docusaurus-plugin-content-blog/tsconfig.client.json
new file mode 100644
index 000000000000..5d06aa818c96
--- /dev/null
+++ b/packages/docusaurus-plugin-content-blog/tsconfig.client.json
@@ -0,0 +1,16 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "noEmit": false,
+ "composite": true,
+ "incremental": true,
+ "tsBuildInfoFile": "./lib/.tsbuildinfo-client",
+ "moduleResolution": "bundler",
+ "module": "esnext",
+ "target": "esnext",
+ "rootDir": "src",
+ "outDir": "lib"
+ },
+ "include": ["src/client", "src/*.d.ts"],
+ "exclude": ["**/__tests__/**"]
+}
diff --git a/packages/docusaurus-plugin-content-blog/tsconfig.json b/packages/docusaurus-plugin-content-blog/tsconfig.json
index e16d5c2c5d33..3936df64b7e4 100644
--- a/packages/docusaurus-plugin-content-blog/tsconfig.json
+++ b/packages/docusaurus-plugin-content-blog/tsconfig.json
@@ -1,5 +1,6 @@
{
"extends": "../../tsconfig.json",
+ "references": [{"path": "./tsconfig.client.json"}],
"compilerOptions": {
"noEmit": false,
"incremental": true,
@@ -8,5 +9,5 @@
"outDir": "lib"
},
"include": ["src"],
- "exclude": ["**/__tests__/**"]
+ "exclude": ["src/client", "**/__tests__/**"]
}
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
index 4aa9c33ab2fb..0041a7e88f3a 100644
--- a/packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/BlogPostPage/StructuredData/index.tsx
@@ -10,9 +10,8 @@ import {
useBlogPostStructuredData,
StructuredData,
} from '@docusaurus/theme-common';
-import type {Props} from '@theme/BlogPostPage/StructuredData';
-export default function BlogPostStructuredData(props: Props): JSX.Element {
- const structuredData = useBlogPostStructuredData(props);
+export default function BlogPostStructuredData(): JSX.Element {
+ const structuredData = useBlogPostStructuredData();
return ;
}
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx
index 0d97a6386752..6d7ed51a7fd5 100644
--- a/packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx
+++ b/packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx
@@ -66,11 +66,7 @@ export default function BlogPostPage(props: Props): JSX.Element {
ThemeClassNames.page.blogPostPage,
)}>
-
+
diff --git a/packages/docusaurus-theme-common/src/utils/structuredDataUtils.ts b/packages/docusaurus-theme-common/src/utils/structuredDataUtils.ts
index 99743766c640..eb8cea1ad1b3 100644
--- a/packages/docusaurus-theme-common/src/utils/structuredDataUtils.ts
+++ b/packages/docusaurus-theme-common/src/utils/structuredDataUtils.ts
@@ -7,8 +7,9 @@
import {useBaseUrlUtils, type BaseUrlUtils} from '@docusaurus/useBaseUrl';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
+import {useBlogMetadata} from '@docusaurus/plugin-content-blog/client';
import type {Props as BlogListPageStructuredDataProps} from '@theme/BlogListPage/StructuredData';
-import type {Props as BlogPostPageStructuredDataProps} from '@theme/BlogPostPage/StructuredData';
+import {useBlogPost} from '../contexts/blogPost';
import type {
Blog,
BlogPosting,
@@ -88,7 +89,7 @@ export function useBlogListPageStructuredData(
const url = `${siteConfig.url}${permalink}`;
// details on structured data support: https://schema.org/Blog
- const blogStructuredData: WithContext = {
+ return {
'@context': 'https://schema.org',
'@type': 'Blog',
'@id': url,
@@ -99,16 +100,14 @@ export function useBlogListPageStructuredData(
getBlogPost(blogItem.content, siteConfig, withBaseUrl),
),
};
-
- return blogStructuredData;
}
-export function useBlogPostStructuredData(
- props: BlogPostPageStructuredDataProps,
-): WithContext {
+export function useBlogPostStructuredData(): WithContext {
+ const blogMetadata = useBlogMetadata();
+ const {assets, metadata} = useBlogPost();
const {siteConfig} = useDocusaurusContext();
const {withBaseUrl} = useBaseUrlUtils();
- const {assets, metadata} = props;
+
const {date, title, description, frontMatter} = metadata;
const image = assets.image ?? frontMatter.image;
@@ -119,7 +118,7 @@ export function useBlogPostStructuredData(
// details on structured data support: https://schema.org/BlogPosting
// BlogPosting is one of the structured data types that Google explicitly
// supports: https://developers.google.com/search/docs/appearance/structured-data/article#structured-data-type-definitions
- const blogPostStructuredData: WithContext = {
+ return {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
'@id': url,
@@ -134,12 +133,10 @@ export function useBlogPostStructuredData(
...(keywords ? {keywords} : {}),
isPartOf: {
'@type': 'Blog',
- '@id': `${siteConfig.url}${props.blogMetadata.blogBasePath}`,
- name: props.blogMetadata.blogTitle,
+ '@id': `${siteConfig.url}${blogMetadata.blogBasePath}`,
+ name: blogMetadata.blogTitle,
},
};
-
- return blogPostStructuredData;
}
/** @returns A {@link https://schema.org/Person} constructed from the {@link Author} */
diff --git a/packages/docusaurus-types/src/routing.d.ts b/packages/docusaurus-types/src/routing.d.ts
index 7d1129c2a0a6..5c5ad90f1b4f 100644
--- a/packages/docusaurus-types/src/routing.d.ts
+++ b/packages/docusaurus-types/src/routing.d.ts
@@ -70,7 +70,7 @@ export type RouteContext = {
/**
* Plugin-specific context data.
*/
- data?: object | undefined;
+ data?: {[key: string]: unknown};
};
/**