Aller au contenu principal
Version : 3.4.0

Cycle de vie des API

Pendant la construction, les plugins sont chargés en parallÚle pour récupérer leur propre contenu et les rendre aux routes. Les plugins peuvent également configurer webpack ou post-traiter les fichiers générés.

async loadContent()​

Les plugins doivent utiliser ce cycle de vie pour rĂ©cupĂ©rer des sources de donnĂ©es (systĂšme de fichiers, API distante, CMS sans entĂȘte, etc) ou pour effectuer un traitement du serveur. La valeur retournĂ©e est le contenu dont il a besoin.

Par exemple, ce plugin ci-dessous renvoie un entier aléatoire compris entre 1 et 10 comme contenu.

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})​

Les donnĂ©es qui ont Ă©tĂ© chargĂ©es dans loadContent seront consommĂ©es dans contentLoaded. Il peut ĂȘtre rendu sur des routes, enregistrĂ©s en tant que donnĂ©es globales, etc.

content​

contentLoaded sera appelé aprÚs que loadContent soit fait. La valeur retournée de loadContent() sera passée à contentLoaded comme content.

actions​

actions contient trois fonctions :

addRoute(config: RouteConfig): void​

Créez une route pour l'ajouter au site web.

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>​

Une callback dĂ©clarative pour crĂ©er des donnĂ©es statiques (gĂ©nĂ©ralement JSON ou string) qui peuvent ĂȘtre fournies ultĂ©rieurement Ă  vos routes comme props. Prend le nom du fichier et les donnĂ©es Ă  stocker, et renvoie le chemin du fichier de donnĂ©es actuel.

Par exemple, ce plugin ci-dessous crĂ©e une page /friends qui affiche Vos amis sont : Yangshun, Sebastien :

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

export default function FriendsComponent({friends}) {
return <div>Vos amis sont {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;
// Crée friends.json
const friends = ['Yangshun', 'Sebastien'];
const friendsJsonPath = await createData(
'friends.json',
JSON.stringify(friends),
);

// Ajoute la route '/friends' et assure-vous qu'il reçoit la props friends
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
modules: {
// propName -> chemin fichier JSON
friends: friendsJsonPath,
},
exact: true,
});
},
};
}

setGlobalData(data: any): void​

Cette fonction permet de crĂ©er des donnĂ©es globales de plugin, qui peuvent ĂȘtre lues depuis n'importe quelle page, y compris les pages crĂ©Ă©es par d'autres plugins et la mise en page de votre thĂšme.

Ces données deviennent accessibles pour votre code cÎté client/thÚme à travers les hooks useGlobalData et usePluginData.

attention

Les donnĂ©es globales sont... globales : leurs tailles affectent le temps de chargement de toutes les pages de votre site, alors essayez de les garder petites. PrĂ©fĂ©rez createData et des donnĂ©es spĂ©cifiques Ă  la page dans la mesure du possible.

Par exemple, ce plugin ci-dessous crĂ©e une page /friends qui affiche Vos amis sont : 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>Vos amis sont {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;
// Crée des données globales friends
setGlobalData({friends: ['Yangshun', 'Sebastien']});

// Ajoute la route '/friends'
addRoute({
path: '/friends',
component: '@site/src/components/Friends.js',
exact: true,
});
},
};
}

configureWebpack(config, isServer, utils, content)​

Modifie la configuration interne de webpack. Si la valeur retournée est un objet JavaScript, elle sera fusionnée dans la configuration finale en utilisant webpack-merge. Si c'est une fonction, elle sera appelée et recevra config comme premier argument et un drapeau isServer comme second argument.

attention

L'API de configureWebpack sera modifiée dans le futur pour accepter un objet (configureWebpack({config, isServer, utils, content}))

config​

configureWebpack est appelée avec config générée selon la construction du client/serveur. Vous pouvez le considérer comme la configuration de base avec laquelle il faut fusionner.

isServer​

configureWebpack sera appelée à la fois dans la construction du serveur et dans la construction du client. La construction du serveur reçoit true et la construction du client reçoit false pour isServer.

utils​

configureWebpack reçoit Ă©galement un objet utilitaire :

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

Vous pouvez les utiliser pour retourner votre configuration webpack sous certaines conditions.

Par exemple, ce plugin ci-dessous modifie la configuration de webpack pour transpiler les fichiers .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 sera appelé aussi avec le contenu chargé par le plugin.

StratĂ©gie de fusion​

Nous fusionnons les parties de configuration Webpack des plugins dans la configuration globale de Webpack en utilisant webpack-merge.

Il est possible de spĂ©cifier la stratĂ©gie de fusion. Par exemple, si vous voulez qu'une rĂšgle de webpack soit placĂ©e au dĂ©but au lieu d'ĂȘtre ajoutĂ©e Ă  la fin :

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]},
};
},
};
}

Lisez la documentation de la stratégie de webpack-fusion pour plus de détails.

Configuration du serveur de dev​

Le serveur de dĂ©veloppement peut ĂȘtre configurĂ© en renvoyant un champ devServer.

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

configurePostCss(options)​

Modifie postcssOptions de postcss-loader pendant la génération du bundle client.

Devrait retourner le postcssOptions muté.

Par dĂ©faut, postcssOptions ressemble Ă  ceci :

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

Exemple :

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

postBuild(props)​

Appelée quand une version (production) se termine.

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;
}

Exemple :

docusaurus-plugin/src/index.js
export default function (context, options) {
return {
name: 'docusaurus-plugin',
async postBuild({siteConfig = {}, routesPaths = [], outDir}) {
// Affiche dans la console toutes les routes rendues.
routesPaths.map((route) => {
console.log(route);
});
},
};
}

injectHtmlTags({content})​

Injecte les balises HTML head et/ou body vers le HTML générées de Docusaurus.

injectHtmlTags sera appelé aussi avec le contenu chargé par le plugin.

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

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

type HtmlTagObject = {
/**
* Attributs de la balise HTML
* Par exemple `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
*/
attributes?: {
[attributeName: string]: string | boolean;
};
/**
* Le nom de la balise par exemple `div`, `script`, `link`, `meta`
*/
tagName: string;
/**
* L'intérieur de l'HTML
*/
innerHTML?: string;
};

Exemple :

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>`],
};
},
};
}

Les balises seront ajoutés comme ceci:

  • headTags sera insĂ©rĂ© avant la balise de fermeture </head> aprĂšs les scripts ajoutĂ©s par config.
  • preBodyTags sera insĂ©rĂ© aprĂšs la balise ouvrante <body> avant tout Ă©lĂ©ment enfant.
  • postBodyTags sera insĂ©rĂ© avant la balise fermante </body> aprĂšs tout Ă©lĂ©ment enfant.

getClientModules()​

Retourne un tableau de chemins vers les modules client qui doivent ĂȘtre importĂ©s dans le bundle client.

À titre d'exemple, pour que votre thĂšme puisse charger un fichier customCss ou customJs Ă  partir des options passĂ©es par l'utilisateur :

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