跳到主要内容

Docusaurus 的客户端 API

Docusaurus 提供了一组客户端 API,对于构建网站很有帮助。

组件

<ErrorBoundary />

This component creates a React error boundary.

Use it to wrap components that might throw, and display a fallback when that happens instead of crashing the whole app.

import React from 'react';
import ErrorBoundary from '@docusaurus/ErrorBoundary';

const SafeComponent = () => (
<ErrorBoundary
fallback={({error, tryAgain}) => (
<div>
<p>This component crashed because of error: {error.message}.</p>
<button onClick={tryAgain}>Try Again!</button>
</div>
)}>
<SomeDangerousComponentThatMayThrow />
</ErrorBoundary>
);
提示

To see it in action, click here:

信息

Docusaurus uses this component to catch errors within the theme's layout, and also within the entire app.

备注

This component doesn't catch build-time errors and only protects against client-side render errors that can happen when using stateful React components.

Props

  • fallback: an optional render callback returning a JSX element. It will receive an object with 2 attributes: error, the error that was caught, and tryAgain, a function (() => void) callback to reset the error in the component and try rendering it again. If not present, @theme/Error will be rendered instead. @theme/Error is used for the error boundaries wrapping the site, above the layout.
警告

The fallback prop is a callback, and not a React functional component. You can't use React hooks inside this callback.

这是一个可重用 React 组件,用于管理对 HTML 文档标头(即 <head> 中的标签)的修改。此组件接收纯 HTML 标签并输出纯 HTML 标签,对初学者很友好。此组件始对 React Helmet 的二次包装。

用法示例:

import React from 'react';
import Head from '@docusaurus/Head';

const MySEO = () => (
<Head>
<meta property="og:description" content="My custom description" />
<meta charSet="utf-8" />
<title>My Title</title>
<link rel="canonical" href="http://mysite.com/example" />
</Head>
);

嵌套或靠后定义的组件将覆盖之前的定义:

<Parent>
<Head>
<title>My Title</title>
<meta name="description" content="Helmet application" />
</Head>
<Child>
<Head>
<title>Nested Title</title>
<meta name="description" content="Nested component" />
</Head>
</Child>
</Parent>

输出为:

<head>
<title>Nested Title</title>
<meta name="description" content="Nested component" />
</head>

此组件让你可以链接站内页面并使用被称为预加载(preloading)的强大功能。预加载功能用于预取资源,以便在用户使用此组件切换页面时取回页面资源。我们利用 IntersectionObserver 检测到<Link> 处于视口(viewport)中时发起一个低优先级的资源请求,并且利用 onMouseOver 事件来发起一个高优先级的资源请求(因为这是用户的明确目的)。

此组件是对 react-router 的 <Link> 组件的二次包装,并添加了专门对 Docusaurus 的增强功能。所有传递过来的参数(props)都将透传给 react-router 的 <Link> 组件。

可用于指向站外的链接,并且会被自动添加这些属性:target="_blank" rel="noopener noreferrer"

import React from 'react';
import Link from '@docusaurus/Link';

const Page = () => (
<div>
<p>
Check out my <Link to="/blog">blog</Link>!
</p>
<p>
Follow me on <Link to="https://twitter.com/docusaurus">Twitter</Link>!
</p>
</div>
);

to:字符串类型

目标位置。例如: /docs/introduction

<Link to="/courses" />
提示

Prefer this component to vanilla <a> tags because Docusaurus does a lot of optimizations (e.g. broken path detection, prefetching, applying base URL...) if you use <Link>.

<Redirect/>

Rendering a <Redirect> will navigate to a new location. The new location will override the current location in the history stack like server-side redirects (HTTP 3xx) do. You can refer to React Router's Redirect documentation for more info on available props.

用法示例:

import React from 'react';
import {Redirect} from '@docusaurus/router';

const Home = () => {
return <Redirect to="/docs/test" />;
};
备注

@docusaurus/router 实现了 React Router 并支持同样功能。

<BrowserOnly/>

The <BrowserOnly> component permits to render React components only in the browser after the React app has hydrated.

提示

Use it for integrating with code that can't run in Node.js, because the window or document objects are being accessed.

Props

  • children: render function prop returning browser-only JSX. Will not be executed in Node.js
  • fallback (optional): JSX to render on the server (Node.js) and until React hydration completes.

Example with code

import BrowserOnly from '@docusaurus/BrowserOnly';

const MyComponent = () => {
return (
<BrowserOnly>
{() => <span>page url = {window.location.href}</span>}
</BrowserOnly>
);
};

Example with a library

import BrowserOnly from '@docusaurus/BrowserOnly';

const MyComponent = (props) => {
return (
<BrowserOnly fallback={<div>Loading...</div>}>
{() => {
const LibComponent = require('some-lib').LibComponent;
return <LibComponent {...props} />;
}}
</BrowserOnly>
);
};

<Interpolate/>

该组件用于对文本中所包含的占位符做替换。

占位符将被替换为动态值和你所选择的 JSX 元素(字符串、链接、styled elements 等)。

参数(Props)

  • children:包含占位符(例如 {placeholderName})的文本
  • values:包含占位符替换值的对象
import React from 'react';
import Link from '@docusaurus/Link';
import Interpolate from '@docusaurus/Interpolate';

export default function VisitMyWebsiteMessage() {
return (
<Interpolate
values={{
firstName: 'Sébastien',
website: (
<Link to="https://docusaurus.io" className="my-website-class">
website
</Link>
),
}}>
{'Hello, {firstName}! How are you? Take a look at my {website}'}
</Interpolate>
);
}

<Translate/>

本地化你的网站 时,<Translate/> 组件将用于 为 React 组件提供对翻译功能的支持,例如翻译你的主页。<Translate> 组件支持 interpolation

The translation strings will statically extracted from your code with the docusaurus write-translations CLI and a code.json translation file will be created in website/i18n/[locale].

备注

<Translate/> 组件的参数(props)只能是硬编码的字符串

Apart from the values prop used for interpolation, it is not possible to use variables, or the static extraction wouldn't work.

参数(Props)

  • children: untranslated string in the default site locale (can contain interpolation placeholders)
  • id: optional value to be used as the key in JSON translation files
  • description: optional text to help the translator
  • values: optional object containing interpolation placeholder values

示例

src/pages/index.js
import React from 'react';
import Layout from '@theme/Layout';

import Translate from '@docusaurus/Translate';

export default function Home() {
return (
<Layout>
<h1>
<Translate
id="homepage.title"
description="The homepage welcome message">
Welcome to my website
</Translate>
</h1>
<main>
<Translate values={{firstName: 'Sébastien'}}>
{'Welcome, {firstName}! How are you?'}
</Translate>
</main>
</Layout>
);
}
备注

You can even omit the children prop and specify a translation string in your code.json file manually after running the docusaurus write-translations CLI command.

<Translate id="homepage.title" />

React 钩子(Hooks)

useDocusaurusContext

React hook to access Docusaurus Context. The context contains the siteConfig object from docusaurus.config.js and some additional site metadata.

type PluginVersionInformation =
| {readonly type: 'package'; readonly version?: string}
| {readonly type: 'project'}
| {readonly type: 'local'}
| {readonly type: 'synthetic'};

type SiteMetadata = {
readonly docusaurusVersion: string;
readonly siteVersion?: string;
readonly pluginVersions: Record<string, PluginVersionInformation>;
};

type I18nLocaleConfig = {
label: string;
direction: string;
};

type I18n = {
defaultLocale: string;
locales: [string, ...string[]];
currentLocale: string;
localeConfigs: Record<string, I18nLocaleConfig>;
};

type DocusaurusContext = {
siteConfig: DocusaurusConfig;
siteMetadata: SiteMetadata;
globalData: Record<string, unknown>;
i18n: I18n;
codeTranslations: Record<string, string>;
};

用法示例:

import React from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

const MyComponent = () => {
const {siteConfig, siteMetadata} = useDocusaurusContext();
return (
<div>
<h1>{siteConfig.title}</h1>
<div>{siteMetadata.siteVersion}</div>
<div>{siteMetadata.docusaurusVersion}</div>
</div>
);
};
备注

The siteConfig object only contains serializable values (values that are preserved after JSON.stringify()). Functions, regexes, etc. would be lost on the client side.

useIsBrowser

Returns true when the React app has successfully hydrated in the browser.

警告

Use this hook instead of typeof windows !== 'undefined' in React rendering logic.

The first client-side render output (in the browser) must be exactly the same as the server-side render output (Node.js). Not following this rule can lead to unexpected hydration behaviors, as described in The Perils of Rehydration.

Usage example:

import React from 'react';
import useIsBrowser from '@docusaurus/useIsBrowser';

const MyComponent = () => {
const isBrowser = useIsBrowser();
return <div>{isBrowser ? 'Client' : 'Server'}</div>;
};

useBaseUrl

此 React 钩子(hook)用于将网站的 baseUrl 添加到某个字符串前面。

警告

请勿将其用于普通链接!

默认情况下,/baseUrl/ 前缀会被自动添加到所有 绝对路径 前面:

  • Markdown:[link](/my/path) 将连接到 /baseUrl/my/path
  • React: <Link to="/my/path/">link</Link> 将连接到 /baseUrl/my/path

参数

type BaseUrlOptions = {
forcePrependBaseUrl: boolean;
absolute: boolean;
};

用法示例:

import React from 'react';
import useBaseUrl from '@docusaurus/useBaseUrl';

const SomeImage = () => {
const imgSrc = useBaseUrl('/img/myImage.png');
return <img src={imgSrc} />;
};
提示

在大多数情况下,你并不需要使用 useBaseUrl

针对 静态资源 的引用,推荐使用 require()

<img src={require('@site/static/img/myImage.png').default} />

useBaseUrlUtils

有时,useBaseUrl 还不够好用。而 useBaseUrlUtils 能够返回一组额外的与网站的 baseUrl 相关的辅助函数。

  • withBaseUrl: useful if you need to add base URLs to multiple URLs at once.
import React from 'react';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';

const Component = () => {
const urls = ['/a', '/b'];
const {withBaseUrl} = useBaseUrlUtils();
const urlsWithBaseUrl = urls.map(withBaseUrl);
return <div>{/* ... */}</div>;
};

useGlobalData

此 React 钩子(hook)用于访问所有插件所创建的全局数据。

Global data is namespaced by plugin name then by plugin ID.

信息

Plugin ID is only useful when a plugin is used multiple times on the same site. Each plugin instance is able to create its own global data.

type GlobalData = Record<
PluginName,
Record<
PluginId, // 默认值是 "default"
any // 特定于插件的数据
>
>;

用法示例:

import React from 'react';
import useGlobalData from '@docusaurus/useGlobalData';

const MyComponent = () => {
const globalData = useGlobalData();
const myPluginData = globalData['my-plugin']['default'];
return <div>{myPluginData.someAttribute}</div>;
};
提示

通过 ./docusaurus/globalData.json 文件可以查看站点的全局数据

usePluginData

访问由特定插件实例所创建的全局数据。

This is the most convenient hook to access plugin global data and should be used most of the time.

如果你没有使用插件的多个实例,则 pluginId 是可选的。

function usePluginData(
pluginName: string,
pluginId?: string,
options?: {failfast?: boolean},
);

用法示例:

import React from 'react';
import {usePluginData} from '@docusaurus/useGlobalData';

const MyComponent = () => {
const myPluginData = usePluginData('my-plugin');
return <div>{myPluginData.someAttribute}</div>;
};

useAllPluginInstancesData

访问由特定插件所创建的全局数据。给定插件名称后,该函数将返回以该名称命名的所有插件实例的全局数据,并按照插件 id 标记数据。

function useAllPluginInstancesData(
pluginName: string,
options?: {failfast?: boolean},
);

用法示例:

import React from 'react';
import {useAllPluginInstancesData} from '@docusaurus/useGlobalData';

const MyComponent = () => {
const allPluginInstancesData = useAllPluginInstancesData('my-plugin');
const myPluginData = allPluginInstancesData['default'];
return <div>{myPluginData.someAttribute}</div>;
};

函数

interpolate

对应 <Interpolate> 组件的具有相同功能的函数。

用法

// 简单的字符串替换
function interpolate(text: string, values: Record<string, string>): string;

// JSX interpolation
function interpolate(
text: string,
values: Record<string, ReactNode>,
): ReactNode;

示例

import {interpolate} from '@docusaurus/Interpolate';

const message = interpolate('Welcome {firstName}', {firstName: 'Sébastien'});

translate

对应 <Translate> 组件的具有相同功能的函数。也支持 占位符替换

提示

对于 无法使用组件罕见情况,请使用该函数,例如:

  • 页面的 title 元数据
  • 表单输入框的 placeholder 属性(props)
  • 用于可访问性功能中的 aria-label 属性(props)

用法

function translate(
translation: {message: string; id?: string; description?: string},
values: Record<string, string>,
): string;

示例

src/pages/index.js
import React from 'react';
import Layout from '@theme/Layout';

import {translate} from '@docusaurus/Translate';

export default function Home() {
return (
<Layout
title={translate({message: 'My page meta title'})}>
<img
src={'https://docusaurus.io/logo.png'}
aria-label={
translate(
{
message: 'The logo of site {siteName}',
// 可选
id: 'homepage.logo.ariaLabel',
description: 'The home page logo aria label',
},
{siteName: 'Docusaurus'},
)
}
/>
</Layout>
);
}

模块

ExecutionEnvironment

A module that exposes a few boolean variables to check the current rendering environment.

警告

For React rendering logic, use useIsBrowser() or <BrowserOnly> instead.

Example:

import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';

if (ExecutionEnvironment.canUseDOM) {
require('lib-that-only-works-client-side');
}
变量描述
ExecutionEnvironment.canUseDOM如果在客户端或浏览器中,则为 true;如果是在 Node.js 或预渲染阶段,则为 false
ExecutionEnvironment.canUseEventListeners如果在客户端并且定义了 window.addEventListener,则为true
ExecutionEnvironment.canUseIntersectionObserver如果在客户端并且定义了 IntersectionObserver,则为 true
ExecutionEnvironment.canUseViewport如果在客户端并且定义了 window.screen,则为true

constants

该模块用于为客户端的主题代码暴露一些有用的常量。

import {DEFAULT_PLUGIN_ID} from '@docusaurus/constants';
Named exportValue
DEFAULT_PLUGIN_IDdefault