diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 306c41e37393..2862aa01a402 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -15,6 +15,11 @@ declare module '@generated/docusaurus.config' { export default config; } +declare module '@generated/site-metadata' { + const siteMetadata: any; + export default siteMetadata; +} + declare module '@generated/registry' { const registry: { readonly [key: string]: [() => Promise, string, string]; @@ -37,29 +42,6 @@ declare module '@generated/routesChunkNames' { export default routesChunkNames; } -declare module '@generated/site-metadata' { - /** - * - `type: 'package'`, plugin is in a different package. - * - `type: 'project'`, plugin is in the same docusaurus project. - * - `type: 'local'`, none of plugin's ancestor directory contains any package.json. - * - `type: 'synthetic'`, docusaurus generated internal plugin. - */ - export type PluginVersionInformation = - | {readonly type: 'package'; readonly version?: string} - | {readonly type: 'project'} - | {readonly type: 'local'} - | {readonly type: 'synthetic'}; - - export type DocusaurusSiteMetadata = { - readonly docusaurusVersion: string; - readonly siteVersion?: string; - readonly pluginVersions: Record; - }; - - const siteMetadata: DocusaurusSiteMetadata; - export default siteMetadata; -} - declare module '@theme/*'; declare module '@theme-original/*'; diff --git a/packages/docusaurus-plugin-debug/src/theme/Debug/index.js b/packages/docusaurus-plugin-debug/src/theme/Debug/index.js index 1dc44d973a53..49a3a9f4519c 100644 --- a/packages/docusaurus-plugin-debug/src/theme/Debug/index.js +++ b/packages/docusaurus-plugin-debug/src/theme/Debug/index.js @@ -10,11 +10,12 @@ import Layout from '@theme/Layout'; import registry from '@generated/registry'; import routes from '@generated/routes'; -import siteMetadata from '@generated/site-metadata'; import styles from './styles.module.css'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; function Debug() { + const {siteMetadata} = useDocusaurusContext(); return (
diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 80be2a48c703..f3ad66ee72d0 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -44,9 +44,28 @@ export interface DocusaurusConfig { )[]; } +/** + * - `type: 'package'`, plugin is in a different package. + * - `type: 'project'`, plugin is in the same docusaurus project. + * - `type: 'local'`, none of plugin's ancestor directory contains any package.json. + * - `type: 'synthetic'`, docusaurus generated internal plugin. + */ +export type DocusaurusPluginVersionInformation = + | {readonly type: 'package'; readonly version?: string} + | {readonly type: 'project'} + | {readonly type: 'local'} + | {readonly type: 'synthetic'}; + +export interface DocusaurusSiteMetadata { + readonly docusaurusVersion: string; + readonly siteVersion?: string; + readonly pluginVersions: Record; +} + export interface DocusaurusContext { - siteConfig?: DocusaurusConfig; - isClient?: boolean; + siteConfig: DocusaurusConfig; + siteMetadata: DocusaurusSiteMetadata; + isClient: boolean; } export interface Preset { diff --git a/packages/docusaurus/src/client/App.tsx b/packages/docusaurus/src/client/App.tsx index 4bb3aba05dd7..e4f940b2cc58 100644 --- a/packages/docusaurus/src/client/App.tsx +++ b/packages/docusaurus/src/client/App.tsx @@ -9,6 +9,7 @@ import React, {useEffect, useState} from 'react'; import routes from '@generated/routes'; import siteConfig from '@generated/docusaurus.config'; +import siteMetadata from '@generated/site-metadata'; import renderRoutes from './exports/renderRoutes'; import DocusaurusContext from './exports/context'; import PendingNavigation from './PendingNavigation'; @@ -23,7 +24,7 @@ function App(): JSX.Element { }, []); return ( - + {renderRoutes(routes)} diff --git a/packages/docusaurus/src/client/exports/context.ts b/packages/docusaurus/src/client/exports/context.ts index d5b4f3c5c2e3..b7704806247c 100644 --- a/packages/docusaurus/src/client/exports/context.ts +++ b/packages/docusaurus/src/client/exports/context.ts @@ -8,4 +8,4 @@ import React from 'react'; import {DocusaurusContext} from '@docusaurus/types'; -export default React.createContext({}); +export default React.createContext(null); diff --git a/packages/docusaurus/src/client/exports/useDocusaurusContext.ts b/packages/docusaurus/src/client/exports/useDocusaurusContext.ts index 7dea1515aba6..eb67a6a63840 100644 --- a/packages/docusaurus/src/client/exports/useDocusaurusContext.ts +++ b/packages/docusaurus/src/client/exports/useDocusaurusContext.ts @@ -10,7 +10,12 @@ import context from './context'; import {DocusaurusContext} from '@docusaurus/types'; function useDocusaurusContext(): DocusaurusContext { - return useContext(context); + const docusaurusContext = useContext(context); + if (docusaurusContext === null) { + // should not happen normally + throw new Error('Docusaurus context not provided'); + } + return docusaurusContext; } export default useDocusaurusContext; diff --git a/packages/docusaurus/src/server/index.ts b/packages/docusaurus/src/server/index.ts index c1d729027354..73ca1be27322 100644 --- a/packages/docusaurus/src/server/index.ts +++ b/packages/docusaurus/src/server/index.ts @@ -6,7 +6,6 @@ */ import {generate} from '@docusaurus/utils'; -import {DocusaurusSiteMetadata} from '@generated/site-metadata'; import path, {join} from 'path'; import { BUILD_DIR_NAME, @@ -22,6 +21,7 @@ import loadRoutes from './routes'; import loadThemeAlias from './themes'; import { DocusaurusConfig, + DocusaurusSiteMetadata, LoadContext, PluginConfig, Props, diff --git a/packages/docusaurus/src/server/plugins/init.ts b/packages/docusaurus/src/server/plugins/init.ts index 93a8fcb67ae9..b388fe291178 100644 --- a/packages/docusaurus/src/server/plugins/init.ts +++ b/packages/docusaurus/src/server/plugins/init.ts @@ -13,8 +13,8 @@ import { Plugin, PluginConfig, ValidationSchema, + DocusaurusPluginVersionInformation, } from '@docusaurus/types'; -import {PluginVersionInformation} from '@generated/site-metadata'; import {CONFIG_FILE_NAME} from '../../constants'; import {getPluginVersion} from '../versions'; @@ -40,7 +40,7 @@ function validateAndStrip(schema: ValidationSchema, options: Partial) { } export type PluginWithVersionInformation = Plugin & { - readonly version: PluginVersionInformation; + readonly version: DocusaurusPluginVersionInformation; }; export default function initPlugins({ diff --git a/packages/docusaurus/src/server/versions/index.ts b/packages/docusaurus/src/server/versions/index.ts index 03114a171227..3b312c6e0106 100644 --- a/packages/docusaurus/src/server/versions/index.ts +++ b/packages/docusaurus/src/server/versions/index.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {PluginVersionInformation} from '@generated/site-metadata'; +import {DocusaurusPluginVersionInformation} from '@docusaurus/types'; import {existsSync, lstatSync} from 'fs-extra'; import {dirname, join} from 'path'; @@ -23,7 +23,7 @@ export function getPackageJsonVersion( export function getPluginVersion( pluginPath: string, siteDir: string, -): PluginVersionInformation { +): DocusaurusPluginVersionInformation { let potentialPluginPackageJsonDirectory = dirname(pluginPath); while (potentialPluginPackageJsonDirectory !== '/') { const packageJsonPath = join( diff --git a/website/docs/configuration.md b/website/docs/configuration.md index 19d3164031b4..16c443625c11 100644 --- a/website/docs/configuration.md +++ b/website/docs/configuration.md @@ -137,8 +137,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; const Hello = () => { // highlight-start - const context = useDocusaurusContext(); - const {siteConfig = {}} = context; + const {siteConfig} = useDocusaurusContext(); // highlight-end const {title, tagline} = siteConfig; diff --git a/website/docs/docusaurus-core.md b/website/docs/docusaurus-core.md index bf7264fb921a..6fa9bfbb50bf 100644 --- a/website/docs/docusaurus-core.md +++ b/website/docs/docusaurus-core.md @@ -132,26 +132,42 @@ function MyComponent() { ### `useDocusaurusContext` -React hook to access Docusaurus Context. Context contains `siteConfig` object from [docusaurus.config.js](docusaurus.config.js.md). +React hook to access Docusaurus Context. Context contains `siteConfig` object from [docusaurus.config.js](docusaurus.config.js.md), and some additional site metadata. ```ts +type DocusaurusPluginVersionInformation = + | {readonly type: 'package'; readonly version?: string} + | {readonly type: 'project'} + | {readonly type: 'local'} + | {readonly type: 'synthetic'}; + +interface DocusaurusSiteMetadata { + readonly docusaurusVersion: string; + readonly siteVersion?: string; + readonly pluginVersions: Record; +} + interface DocusaurusContext { - siteConfig?: DocusaurusConfig; + siteConfig: DocusaurusConfig; + siteMetadata: DocusaurusSiteMetadata; } ``` Usage example: -```jsx {2,5} +```jsx {5,8,9} import React from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -const Test = () => { - const context = useDocusaurusContext(); - const {siteConfig = {}} = context; - const {title} = siteConfig; - - return

{title}

; +const MyComponent = () => { + const {siteConfig, siteMetadata} = useDocusaurusContext(); + return ( +
+

{siteConfig.title}

+
{siteMetadata.siteVersion}
+
{siteMetadata.docusaurusVersion}
+
+ ); }; ```