feat(v2): useDocusaurusContext().siteMetadata (#3058)

This commit is contained in:
Sébastien Lorber 2020-07-16 12:46:21 +02:00 committed by GitHub
parent 5d08ef8ef1
commit 1272ab83fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 68 additions and 45 deletions

View file

@ -15,6 +15,11 @@ declare module '@generated/docusaurus.config' {
export default config; export default config;
} }
declare module '@generated/site-metadata' {
const siteMetadata: any;
export default siteMetadata;
}
declare module '@generated/registry' { declare module '@generated/registry' {
const registry: { const registry: {
readonly [key: string]: [() => Promise<any>, string, string]; readonly [key: string]: [() => Promise<any>, string, string];
@ -37,29 +42,6 @@ declare module '@generated/routesChunkNames' {
export default 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<string, PluginVersionInformation>;
};
const siteMetadata: DocusaurusSiteMetadata;
export default siteMetadata;
}
declare module '@theme/*'; declare module '@theme/*';
declare module '@theme-original/*'; declare module '@theme-original/*';

View file

@ -10,11 +10,12 @@ import Layout from '@theme/Layout';
import registry from '@generated/registry'; import registry from '@generated/registry';
import routes from '@generated/routes'; import routes from '@generated/routes';
import siteMetadata from '@generated/site-metadata';
import styles from './styles.module.css'; import styles from './styles.module.css';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
function Debug() { function Debug() {
const {siteMetadata} = useDocusaurusContext();
return ( return (
<Layout permalink="__docusaurus/debug" title="Debug"> <Layout permalink="__docusaurus/debug" title="Debug">
<main className={styles.Container}> <main className={styles.Container}>

View file

@ -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<string, DocusaurusPluginVersionInformation>;
}
export interface DocusaurusContext { export interface DocusaurusContext {
siteConfig?: DocusaurusConfig; siteConfig: DocusaurusConfig;
isClient?: boolean; siteMetadata: DocusaurusSiteMetadata;
isClient: boolean;
} }
export interface Preset { export interface Preset {

View file

@ -9,6 +9,7 @@ import React, {useEffect, useState} from 'react';
import routes from '@generated/routes'; import routes from '@generated/routes';
import siteConfig from '@generated/docusaurus.config'; import siteConfig from '@generated/docusaurus.config';
import siteMetadata from '@generated/site-metadata';
import renderRoutes from './exports/renderRoutes'; import renderRoutes from './exports/renderRoutes';
import DocusaurusContext from './exports/context'; import DocusaurusContext from './exports/context';
import PendingNavigation from './PendingNavigation'; import PendingNavigation from './PendingNavigation';
@ -23,7 +24,7 @@ function App(): JSX.Element {
}, []); }, []);
return ( return (
<DocusaurusContext.Provider value={{siteConfig, isClient}}> <DocusaurusContext.Provider value={{siteConfig, siteMetadata, isClient}}>
<PendingNavigation routes={routes}> <PendingNavigation routes={routes}>
{renderRoutes(routes)} {renderRoutes(routes)}
</PendingNavigation> </PendingNavigation>

View file

@ -8,4 +8,4 @@
import React from 'react'; import React from 'react';
import {DocusaurusContext} from '@docusaurus/types'; import {DocusaurusContext} from '@docusaurus/types';
export default React.createContext<DocusaurusContext>({}); export default React.createContext<DocusaurusContext | null>(null);

View file

@ -10,7 +10,12 @@ import context from './context';
import {DocusaurusContext} from '@docusaurus/types'; import {DocusaurusContext} from '@docusaurus/types';
function useDocusaurusContext(): DocusaurusContext { 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; export default useDocusaurusContext;

View file

@ -6,7 +6,6 @@
*/ */
import {generate} from '@docusaurus/utils'; import {generate} from '@docusaurus/utils';
import {DocusaurusSiteMetadata} from '@generated/site-metadata';
import path, {join} from 'path'; import path, {join} from 'path';
import { import {
BUILD_DIR_NAME, BUILD_DIR_NAME,
@ -22,6 +21,7 @@ import loadRoutes from './routes';
import loadThemeAlias from './themes'; import loadThemeAlias from './themes';
import { import {
DocusaurusConfig, DocusaurusConfig,
DocusaurusSiteMetadata,
LoadContext, LoadContext,
PluginConfig, PluginConfig,
Props, Props,

View file

@ -13,8 +13,8 @@ import {
Plugin, Plugin,
PluginConfig, PluginConfig,
ValidationSchema, ValidationSchema,
DocusaurusPluginVersionInformation,
} from '@docusaurus/types'; } from '@docusaurus/types';
import {PluginVersionInformation} from '@generated/site-metadata';
import {CONFIG_FILE_NAME} from '../../constants'; import {CONFIG_FILE_NAME} from '../../constants';
import {getPluginVersion} from '../versions'; import {getPluginVersion} from '../versions';
@ -40,7 +40,7 @@ function validateAndStrip<T>(schema: ValidationSchema<T>, options: Partial<T>) {
} }
export type PluginWithVersionInformation = Plugin<unknown> & { export type PluginWithVersionInformation = Plugin<unknown> & {
readonly version: PluginVersionInformation; readonly version: DocusaurusPluginVersionInformation;
}; };
export default function initPlugins({ export default function initPlugins({

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * 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 {existsSync, lstatSync} from 'fs-extra';
import {dirname, join} from 'path'; import {dirname, join} from 'path';
@ -23,7 +23,7 @@ export function getPackageJsonVersion(
export function getPluginVersion( export function getPluginVersion(
pluginPath: string, pluginPath: string,
siteDir: string, siteDir: string,
): PluginVersionInformation { ): DocusaurusPluginVersionInformation {
let potentialPluginPackageJsonDirectory = dirname(pluginPath); let potentialPluginPackageJsonDirectory = dirname(pluginPath);
while (potentialPluginPackageJsonDirectory !== '/') { while (potentialPluginPackageJsonDirectory !== '/') {
const packageJsonPath = join( const packageJsonPath = join(

View file

@ -137,8 +137,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
const Hello = () => { const Hello = () => {
// highlight-start // highlight-start
const context = useDocusaurusContext(); const {siteConfig} = useDocusaurusContext();
const {siteConfig = {}} = context;
// highlight-end // highlight-end
const {title, tagline} = siteConfig; const {title, tagline} = siteConfig;

View file

@ -132,26 +132,42 @@ function MyComponent() {
### `useDocusaurusContext` ### `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 ```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<string, DocusaurusPluginVersionInformation>;
}
interface DocusaurusContext { interface DocusaurusContext {
siteConfig?: DocusaurusConfig; siteConfig: DocusaurusConfig;
siteMetadata: DocusaurusSiteMetadata;
} }
``` ```
Usage example: Usage example:
```jsx {2,5} ```jsx {5,8,9}
import React from 'react'; import React from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
const Test = () => { const MyComponent = () => {
const context = useDocusaurusContext(); const {siteConfig, siteMetadata} = useDocusaurusContext();
const {siteConfig = {}} = context; return (
const {title} = siteConfig; <div>
<h1>{siteConfig.title}</h1>
return <h1>{title}</h1>; <div>{siteMetadata.siteVersion}</div>
<div>{siteMetadata.docusaurusVersion}</div>
</div>
);
}; };
``` ```