本文へスキップ
バージョン: 3.5.2

ライフサイクルAPI

ビルド中は、プラグインが並列にロードされ、それぞれ独自のコンテンツを取得してルートにレンダリングします。プラグインはWebpackの設定や生成されたファイルのポストプロセスも実行できます。

async loadContent()

プラグインは、このライフサイクルを使用してデータソース(ファイルシステム、リモートAPI、ヘッドレスCMSなど)からフェッチしたり、サーバー側処理を実行します。戻り値は必要なコンテンツです。

たとえば、以下のプラグインは1から10までのランダムな整数をコンテンツとして返します。

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'docusaurus-plugin',
async loadContent() {
return 1 + Math.floor(Math.random() * 10);
},
};
}

async contentLoaded({content, actions})

loadContentでロードされたデータは、contentLoadedで消費されます。ルートへのレンダリング、グローバルデータとしての登録などが可能です。

content

contentLoadedは、loadContentが完了した後に呼び出されます。loadContent()の戻り値は、contentとしてcontentLoadedに渡されます。

actions

actionsには3つの関数が含まれています。

addRoute(config: RouteConfig): void

ウェブサイトに追加するルートを作成します。

export type RouteConfig = {
/**
* With leading slash. Trailing slash will be normalized by config.
*/
path: string;
/**
* Component used to render this route, a path that the bundler can `require`.
*/
component: string;
/**
* Props. Each entry should be `[propName]: pathToPropModule` (created with
* `createData`)
*/
modules?: RouteModules;
/**
* The route context will wrap the `component`. Use `useRouteContext` to
* retrieve what's declared here. Note that all custom route context declared
* here will be namespaced under {@link RouteContext.data}.
*/
context?: RouteModules;
/**
* Nested routes config, useful for "layout routes" having subroutes.
*/
routes?: RouteConfig[];
/**
* React router config option: `exact` routes would not match subroutes.
*/
exact?: boolean;
/**
* React router config option: `strict` routes are sensitive to the presence
* of a trailing slash.
*/
strict?: boolean;
/**
* Used to sort routes.
* Higher-priority routes will be matched first.
*/
priority?: number;
/**
* Optional route metadata
*/
metadata?: RouteMetadata;
/**
* Extra props; will be available on the client side.
*/
[propName: string]: unknown;
};

/**
* Plugin authors can assign extra metadata to the created routes
* It is only available on the Node.js side, and not sent to the browser
* Optional: plugin authors are encouraged but not required to provide it
*
* Some plugins might use this data to provide additional features.
* This is the case of the sitemap plugin to provide support for "lastmod".
* See also: https://github.com/facebook/docusaurus/pull/9954
*/
export type RouteMetadata = {
/**
* The source code file path that led to the creation of the current route
* In official content plugins, this is usually a Markdown or React file
* This path is expected to be relative to the site directory
*/
sourceFilePath?: string;
/**
* The last updated date of this route
* This is generally read from the Git history of the sourceFilePath
* but can also be provided through other means (usually front matter)
*
* This has notably been introduced for adding "lastmod" support to the
* sitemap plugin, see https://github.com/facebook/docusaurus/pull/9954
*/
lastUpdatedAt?: number;
};

type RouteModules = {
[module: string]: Module | RouteModules | RouteModules[];
};

type Module =
| {
path: string;
__import?: boolean;
query?: ParsedUrlQueryInput;
}
| string;

createData(name: string, data: any): Promise<string>

静的データ(一般的にJSONまたは文字列)を作成するための宣言的なコールバックで、後でプロップスとしてルートに提供できます。保存するファイル名とデータを受け取り、実際のデータファイルのパスを返します。

たとえば、以下のプラグインは/friendsページを作成し、Your friends are: Yangshun, Sebastienを表示します。

website/src/components/Friends.js
import React from 'react';

export default function FriendsComponent({friends}) {
return <div>Your friends are {friends.join(',')}</div>;
}
docusaurus-friends-plugin/src/index.js
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {createData, addRoute} = actions;
// Create friends.json
const friends = ['Yangshun', 'Sebastien'];
const friendsJsonPath = await createData(
'friends.json',
JSON.stringify(friends),
);

// Add the '/friends' routes, and ensure it receives the friends props
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
modules: {
// propName -> JSON file path
friends: friendsJsonPath,
},
exact: true,
});
},
};
}

setGlobalData(data: any): void

この関数は、他のプラグインやテーマレイアウトで作成されたページを含む、任意のページから読み取ることができるグローバルなプラグインデータを作成することを可能にします。

このデータは、useGlobalDataおよびusePluginDataフックを介してクライアントサイド/テーマコードからアクセスできるようになります。

警告

グローバルデータはグローバルです。そのサイズはサイトのすべてのページのロード時間に影響するため、小さく保つようにしてください。可能であれば、createDataとページ固有のデータを使用してください。

たとえば、以下のプラグインは/friendsページを作成し、Your friends are: Yangshun, Sebastienを表示します。

website/src/components/Friends.js
import React from 'react';
import {usePluginData} from '@docusaurus/useGlobalData';

export default function FriendsComponent() {
const {friends} = usePluginData('docusaurus-friends-plugin');
return <div>Your friends are {friends.join(',')}</div>;
}
docusaurus-friends-plugin/src/index.js
export default function friendsPlugin(context, options) {
return {
name: 'docusaurus-friends-plugin',
async contentLoaded({content, actions}) {
const {setGlobalData, addRoute} = actions;
// Create friends global data
setGlobalData({friends: ['Yangshun', 'Sebastien']});

// Add the '/friends' routes
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
exact: true,
});
},
};
}

configureWebpack(config, isServer, utils, content)

内部Webpack設定を変更します。戻り値がJavaScriptオブジェクトの場合、webpack-mergeを使用して最終設定にマージされます。関数の場合は、呼び出され、最初の引数としてconfig、2番目の引数としてisServerフラグを受け取ります。

警告

configureWebpackのAPIは、将来的にオブジェクトを受け入れるように変更されます(configureWebpack({config, isServer, utils, content})

config

クライアント/サーバービルドに応じて生成されたconfigを使用してconfigureWebpackが呼び出されます。これはマージする基本設定として扱うことができます。

isServer

configureWebpackは、サーバービルドとクライアントビルドの両方で呼び出されます。サーバービルドはtrueを、クライアントビルドはfalseisServerとして受け取ります。

utils

configureWebpackはユーティリティオブジェクトも受け取ります。

  • getStyleLoaders(isServer: boolean, cssOptions: {[key: string]: any}): Loader[]
  • getJSLoader(isServer: boolean, cacheOptions?: {}): Loader | null

これらを使用して、条件付きでWebpack設定を返すことができます。

たとえば、以下のプラグインはWebpack設定を変更して.fooファイルをトランスパイルします。

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
const {getJSLoader} = utils;
return {
module: {
rules: [
{
test: /\.foo$/,
use: [getJSLoader(isServer), 'my-custom-webpack-loader'],
},
],
},
};
},
};
}

content

configureWebpackは、プラグインによってロードされたコンテンツを使用して呼び出されます。

マージ戦略

プラグインのWebpack設定部分をグローバルなWebpack設定にマージするために、webpack-mergeを使用します。

マージ戦略を指定できます。たとえば、Webpackルールを末尾に追加する代わりに先頭に追加する場合などです。

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
return {
mergeStrategy: {'module.rules': 'prepend'},
module: {rules: [myRuleToPrepend]},
};
},
};
}

詳細については、webpack-merge戦略ドキュメントを参照してください。

開発サーバーの設定

開発サーバーは、devServerフィールドを返すことで設定できます。

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'custom-docusaurus-plugin',
configureWebpack(config, isServer, utils) {
return {
devServer: {
open: '/docs', // Opens localhost:3000/docs instead of localhost:3000/
},
};
},
};
}

configurePostCss(options)

クライアントバンドルの生成中に、postcss-loaderpostcssOptionsを変更します。

変更されたpostcssOptionsを返す必要があります。

デフォルトでは、postcssOptionsは次のようになります。

const postcssOptions = {
ident: 'postcss',
plugins: [require('autoprefixer')],
};

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'docusaurus-plugin',
configurePostCss(postcssOptions) {
// Appends new PostCSS plugin.
postcssOptions.plugins.push(require('postcss-import'));
return postcssOptions;
},
};
}

postBuild(props)

(本番)ビルドが完了したときに呼び出されます。

interface Props {
siteDir: string;
generatedFilesDir: string;
siteConfig: DocusaurusConfig;
outDir: string;
baseUrl: string;
headTags: string;
preBodyTags: string;
postBodyTags: string;
routesPaths: string[];
plugins: Plugin<any>[];
content: Content;
}

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'docusaurus-plugin',
async postBuild({siteConfig = {}, routesPaths = [], outDir}) {
// Print out to console all the rendered routes.
routesPaths.map((route) => {
console.log(route);
});
},
};
}

injectHtmlTags({content})

Docusaurusによって生成されたHTMLにheadタグと/またはbodyタグを挿入します。

injectHtmlTagsは、プラグインによってロードされたコンテンツを使用して呼び出されます。

function injectHtmlTags(): {
headTags?: HtmlTags;
preBodyTags?: HtmlTags;
postBodyTags?: HtmlTags;
};

type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];

type HtmlTagObject = {
/**
* Attributes of the HTML tag
* E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
*/
attributes?: {
[attributeName: string]: string | boolean;
};
/**
* The tag name e.g. `div`, `script`, `link`, `meta`
*/
tagName: string;
/**
* The inner HTML
*/
innerHTML?: string;
};

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'docusaurus-plugin',
loadContent: async () => {
return {remoteHeadTags: await fetchHeadTagsFromAPI()};
},
injectHtmlTags({content}) {
return {
headTags: [
{
tagName: 'link',
attributes: {
rel: 'preconnect',
href: 'https://www.github.com',
},
},
...content.remoteHeadTags,
],
preBodyTags: [
{
tagName: 'script',
attributes: {
charset: 'utf-8',
src: '/noflash.js',
},
},
],
postBodyTags: [`<div> This is post body </div>`],
};
},
};
}

タグは次のように追加されます。

  • headTagsは、設定によって追加されたスクリプトの後、閉じ</head>タグの前に挿入されます。
  • preBodyTagsは、開始<body>タグの後、子要素の前に挿入されます。
  • postBodyTagsは、すべての子要素の後、閉じ</body>タグの前に挿入されます。

getClientModules()

クライアントバンドルにインポートされるクライアントモジュールへのパスの配列を返します。

例として、ユーザーが渡したoptionsからcustomCssまたはcustomJsファイルパスをテーマにロードさせるには

my-theme/src/index.js
export default function (context, options) {
const {customCss, customJs} = options || {};
return {
name: 'name-of-my-theme',
getClientModules() {
return [customCss, customJs];
},
};
}