Ir para o conteúdo principal
Version: 2.0.0-beta.3

APIs de ciclo de vida

caution

Esta seção está em progresso.

As APIs do ciclo de vida são compartilhadas por Temas e Plugins.

validateOptions({options, validate})#

Retorna opções validadas e normalizadas para o plugin. Este método é chamado antes do plugin ser inicializado. Você deve retornar as opções já que as opções retornadas serão passadas para o plugin durante a inicialização.

options#

validateOptions é chamado com options de plugin para validação e normalização.

validate#

validateOptions é chamada com uma função validate que recebe um esquema Joi e opções como argumento, retorna opções validadas e normalizadas. validate tratará automaticamente de erros e configurações de validação.

tip

Joi é recomendado para validação e normalização de opções.

Para evitar a mistura de versões de Joi, use const {Joi} = require("@docusaurus/utils-validation")

Se você não usar o Joi para validação, você pode lançar um erro no caso de opções inválidas e retornar as opções em caso de sucesso.

my-plugin/src/index.js
module.exports = function (context, options) {  return {    name: 'docusaurus-plugin',    // rest of methods  };};
module.exports.validateOptions = ({options, validate}) => {  const validatedOptions = validate(myValidationSchema, options);  return validationOptions;};

Você também pode usar exportações de estilo de módulos ES.

my-plugin/src/index.ts
export default function (context, options) {  return {    name: 'docusaurus-plugin',    // rest of methods  };}
export function validateOptions({options, validate}) {  const validatedOptions = validate(myValidationSchema, options);  return validationOptions;}

validateThemeConfig({themeConfig, validate})#

Retorna a configuração validada e normalizada para o tema.

themeConfig#

validateThemeConfig é chamado com themeConfig fornecido em docusaurus.config.js para validação e normalização.

validate#

validateThemeConfig é chamada com uma função validate que recebe uma função do esquema Joi e themeConfig como argumento, retorna opções validadas e normalizadas. validate tratará automaticamente de erros e configurações de validação.

tip

Joi é recomendado para validação e normalização das configurações do tema.

Para evitar a mistura de versões de Joi, use const {Joi} = require("@docusaurus/utils-validation")

Se você não usar Joi para a validação, você pode lançar um erro no caso de opções inválidas.

my-theme/src/index.js
module.exports = function (context, options) {  return {    name: 'docusaurus-plugin',    // rest of methods  };};
module.exports.validateThemeConfig = ({themeConfig, validate}) => {  const validatedThemeConfig = validate(myValidationSchema, options);  return validatedThemeConfig;};

Você também pode usar exportações de estilo de módulos ES.

my-theme/src/index.ts
export default function (context, options) {  return {    name: 'docusaurus-plugin',    // rest of methods  };}
export function validateThemeConfig({themeConfig, validate}) {  const validatedThemeConfig = validate(myValidationSchema, options);  return validatedThemeConfig;}

getPathsToWatch()#

Especifica os caminhos a serem observados por plug-ins e temas. Os caminhos são monitorados pelo servidor de desenvolvimento para que os ciclos de vida do plugin sejam recarregados quando o conteúdo dos caminhos monitorados muda. Observe que os plugins e módulos de temas são inicialmente chamados com context e option do Node, que você pode usar para encontrar as informações necessárias do diretório sobre o site.

Exemplo:

docusaurus-plugin/src/index.js
const path = require('path');module.exports = function (context, options) {  return {    name: 'docusaurus-plugin',    getPathsToWatch() {      const contentPath = path.resolve(context.siteDir, options.path);      return [`${contentPath}/**/*.{ts,tsx}`];    },  };};

async loadContent()#

Plugins devem usar este ciclo de vida para obter de fontes de dados (sistema de arquivos, API remota, CMS, headless etc) ou fazer algum processamento de servidor.

Por exemplo, este plugin abaixo retorna um inteiro aleatório entre 1 a 10 como conteúdo;

docusaurus-plugin/src/index.js
const path = require('path');module.exports = function (context, options) {  return {    name: 'docusaurus-plugin',    async loadContent() {      return 1 + Math.floor(Math.random() * 10);    },  };};

async contentLoaded({content, actions})#

Plugins devem usar os dados carregados no loadContent e construir as páginas/rotas que consomem os dados carregados (opcional).

content#

contentLoaded será chamado após o loadContent ser concluído, o valor de retorno de loadContent() será passado para contentLoaded como content.

actions#

actions contém duas funções:

  • addRoute(config: RouteConfig): void

Criar uma rota para adicionar ao site.

interface RouteConfig {  path: string;  component: string;  modules?: RouteModule;  routes?: RouteConfig[];  exact?: boolean;  priority?: number;}interface RouteModule {  [module: string]: Module | RouteModule | RouteModule[];}type Module =  | {      path: string;      __import?: boolean;      query?: ParsedUrlQueryInput;    }  | string;
  • createData(name: string, data: any): Promise<string>

Uma função para ajudá-lo a criar dados estáticos (geralmente json ou string), que você pode fornecer às suas rotas como suportes.

Por exemplo, este plugin abaixo cria uma página de /friends que exibe Seus amigos são: 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

Esta função permite criar alguns dados globais do plugin, que podem ser lidos a partir de qualquer página, incluindo as páginas criadas por outros plugins, e o layout do seu tema.

Estes dados se tornam acessíveis para o seu código do lado-cliente/tema, através do useGlobalData e usePluginData.

Depois de criar esses dados, você pode acessá-los com as APIs de ganchos de dados globais.

caution

Dados globais são... globais: seu tamanho afeta o tempo de carregamento de todas as páginas de seu site, então tente mantê-los pequenos.

Prefira createData e dados específicos da página sempre que possível.

Por exemplo, este plugin abaixo cria uma página de /friends que exibe Seus amigos são: Yangshun, Sebastien:

website/src/components/Friends.js
import React from 'react';import {usePluginData} from '@docusaurus/useGlobalData';
export default function FriendsComponent() {  const {friends} = usePluginData('my-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)#

Modifica a configuração interna do webpack. Se o valor de retorno for um objeto JavaScript, ele será mesclado na configuração final usando webpack-merge. Se é uma função, ele será chamado e receberá a config como o primeiro argumento e um isServer como argumento de argumento.

caution

A API de configureWebpack será modificada no futuro para aceitar um objeto (configureWebpack({config, isServer, utils, content})

config#

configureWebpack é chamado com config gerada de acordo com compilação de cliente/servidor. Você pode tratar isto como a configuração base a ser mesclada.

isServer#

configureWebpack será chamado tanto em compilação de servidor quanto na compilação do cliente. A compilação do servidor recebe true e a compilação do cliente recebe false como isServer.

utils#

configureWebpack também recebe um objeto util:

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

Você pode usá-los para retornar seu webpack de forma condicional.

Por exemplo, este plugin abaixo modifica a configuração do webpack para transpilar o arquivo .foo.

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

content#

configureWebpack será chamado com o conteúdo carregado pelo plugin.

Estratégia de merge#

Mesclamos as partes de configuração dos plugins na configuração global do Webpack usando webpack-merge.

É possível especificar a estratégia de mesclagem. Por exemplo, se você quer que uma regra webpack seja anexada em vez de adicionada:

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

Leia o ponto de estratégia de mesclagem web para mais detalhes.

configurePostCss(options)#

Modifica postcssOptions de postcss-loader durante a geração do pacote para clientes.

Deve retornar as postcssOptions modificadas.

Por padrão, as postcssOptions se parecem com isso:

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

Exemplo:

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

postBuild(props)#

Chamada quando termina a compilação de (produção).

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

Exemplo:

docusaurus-plugin/src/index.js
module.exports = 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);      });    },  };};

extendCli(cli)#

Registre um comando extra para melhorar a CLI do Docusaurus. cli é um objeto de commander.

Exemplo:

docusaurus-plugin/src/index.js
module.exports = function (context, options) {  return {    name: 'docusaurus-plugin',    extendCli(cli) {      cli        .command('roll')        .description('Roll a random number between 1 and 1000')        .action(() => {          console.log(Math.floor(Math.random() * 1000 + 1));        });    },  };};

injectHtmlTags({content})#

Injete a cabeça e/ou as tags HTML do Docusaurus no HTML.

injectHtmlTags será chamado de ambos com o conteúdo carregado pelo plugin.

function injectHtmlTags(): {  headTags?: HtmlTags;  preBodyTags?: HtmlTags;  postBodyTags?: HtmlTags;};
type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
interface 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;}

Exemplo:

docusaurus-plugin/src/index.js
module.exports = 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>`],      };    },  };};

getThemePath()#

Retorna o caminho para o diretório onde os componentes do tema podem ser encontrados. Quando seus usuários chamam swizzle, getThemePath é chamado e seu caminho retornado é usado para encontrar seus componentes de tema.

Se você usar o diretório da pasta acima, seu getThemePath pode ser:

my-theme/src/index.js
const path = require('path');
module.exports = function (context, options) {  return {    name: 'name-of-my-theme',    getThemePath() {      return path.resolve(__dirname, './theme');    },  };};

getTypeScriptThemePath()#

Semelhante ao getThemePath(), ele deve retornar o caminho para o diretório onde o código fonte dos componentes do tema TypeScript pode ser encontrado. Componentes do tema neste caminho não serão resolvidos pelo Webpack. Portanto, não é uma substituição de getThemePath(). Em vez disso, esse caminho é apenas para componentes de tema TypeScript.

Se você quiser suportar o swizzling do componente TypeScript para seu tema, você pode fazer o caminho retornado pelo getTypeScriptThemePath() ser o diretório de origem, e fazer o caminho retornado pelo getThemePath() ser a saída JavaScript compilada.

Exemplo:

my-theme/src/index.js
const path = require('path');
module.exports = function (context, options) {  return {    name: 'name-of-my-theme',    getThemePath() {      // Where compiled JavaScript output lives      return path.join(__dirname, '..', 'lib', 'theme');    },    getTypeScriptThemePath() {      // Where TypeScript source code lives      return path.resolve(__dirname, './theme');    },  };};

getSwizzleComponentList()#

Retorna uma lista de componentes estáveis que são considerados seguros para swizzling. Esses componentes serão listados no componente swizzle sem --danger. Todos os componentes são considerados instáveis por padrão. Se uma matriz vazia for retornada, então todos os componentes são considerados instáveis, se undefined for retornado, então todos os componentes são considerados estáveis.

my-theme/src/index.js
const swizzleAllowedComponents = [  'CodeBlock',  'DocSidebar',  'Footer',  'NotFound',  'SearchBar',  'hooks/useTheme',  'prism-include-languages',];
module.exports.getSwizzleComponentList = () => swizzleAllowedComponents;

getClientModules()#

Retorna um array de caminhos para os módulos que devem ser importados no pacote do cliente. Estes módulos são importados globalmente antes do React até renderiza a interface inicial do usuário.

Como exemplo, para fazer com que seu tema carregue um caminho de arquivo customCss ou customJs das opções passadas pelo usuário:

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

i18n lifecycles#

getTranslationFiles({content})#

Os plugins declaram os arquivos de tradução JSON que eles querem usar.

Retorna os arquivos de tradução {path: string, content: ChromeI18nJSON}:

  • Path: em relação à pasta localizada i18n/<locale>/pluginName. A extensão .json não é necessária.
  • Content: usando o formato JSON do Chrome i18n

Esses arquivos serão escritos pelo write-translations CLI para a subpasta do plugin i18n, e será lido na localidade apropriada antes de chamar translateContent() e translateThemeConfig()

Exemplo:

module.exports = function (context, options) {  return {    name: 'my-plugin',    async getTranslationFiles({content}) {      return [        {          path: 'sidebar-labels',          content: {            someSidebarLabel: {              message: 'Some Sidebar Label',              description: 'A label used in my plugin in the sidebar',            },            someLabelFromContent: content.myLabel,          },        },      ];    },  };};

translateContent({content,translationFiles})#

Traduza o conteúdo do plugin, usando os arquivos de tradução localizados.

Retorna o conteúdo do plugin localizado.

O ciclo de vida contentLoaded() será chamado com o conteúdo do plugin localizado retornado por translateContent().

Exemplo:

module.exports = function (context, options) {  return {    name: 'my-plugin',    translateContent({content, translationFiles}) {      const myTranslationFile = translationFiles.find(        (f) => f.path === 'myTranslationFile',      );      return {        ...content,        someContentLabel: myTranslationFile.someContentLabel.message,      };    },  };};

translateThemeConfig({themeConfig,translationFiles})#

Traduza os rótulos do site themeConfig, usando os arquivos de tradução localizados.

Retorna o themeConfig localizado.

Exemplo:

module.exports = function (context, options) {  return {    name: 'my-theme',    translateThemeConfig({themeConfig, translationFiles}) {      const myTranslationFile = translationFiles.find(        (f) => f.path === 'myTranslationFile',      );      return {        ...themeConfig,        someThemeConfigLabel: myTranslationFile.someThemeConfigLabel.message,      };    },  };};

async getDefaultCodeTranslationMessages()#

Temas usando a <Translate> API podem fornecer mensagens de tradução de código padrão.

Deve retornar mensagens em Record<string,string>, onde chaves são Ids de tradução e valores são mensagens (sem descrição) localizadas usando o local atual do site.

Exemplo:

module.exports = function (context, options) {  return {    name: 'my-theme',    async getDefaultCodeTranslationMessages() {      return readJsonFile(`${context.i18n.currentLocale}.json`);    },  };};

Exemplo#

Aqui está um modelo mental para uma implementação de plug-in presunçosa.

const DEFAULT_OPTIONS = {  // Some defaults.};
// A JavaScript function that returns an object.// `context` is provided by Docusaurus. Example: siteConfig can be accessed from context.// `opts` is the user-defined options.module.exports = function (context, opts) {  // Merge defaults with user-defined options.  const options = {...DEFAULT_OPTIONS, ...options};
  return {    // A compulsory field used as the namespace for directories to cache    // the intermediate data for each plugin.    // If you're writing your own local plugin, you will want it to    // be unique in order not to potentially conflict with imported plugins.    // A good way will be to add your own project name within.    name: 'docusaurus-my-project-cool-plugin',
    async loadContent() {      // The loadContent hook is executed after siteConfig and env has been loaded.      // You can return a JavaScript object that will be passed to contentLoaded hook.    },
    async contentLoaded({content, actions}) {      // The contentLoaded hook is done after loadContent hook is done.      // `actions` are set of functional API provided by Docusaurus (e.g. addRoute)    },
    async postBuild(props) {      // After docusaurus <build> finish.    },
    // TODO    async postStart(props) {      // docusaurus <start> finish    },
    // TODO    afterDevServer(app, server) {      // https://webpack.js.org/configuration/dev-server/#devserverbefore    },
    // TODO    beforeDevServer(app, server) {      // https://webpack.js.org/configuration/dev-server/#devserverafter    },
    configureWebpack(config, isServer, utils, content) {      // Modify internal webpack config. If returned value is an Object, it      // will be merged into the final config using webpack-merge;      // If the returned value is a function, it will receive the config as the 1st argument and an isServer flag as the 2nd argument.    },
    getPathsToWatch() {      // Paths to watch.    },
    getThemePath() {      // Returns the path to the directory where the theme components can      // be found.    },
    getClientModules() {      // Return an array of paths to the modules that are to be imported      // in the client bundle. These modules are imported globally before      // React even renders the initial UI.    },
    extendCli(cli) {      // Register an extra command to enhance the CLI of Docusaurus    },
    injectHtmlTags({content}) {      // Inject head and/or body HTML tags.    },
    async getTranslationFiles({content}) {      // Return translation files    },
    translateContent({content, translationFiles}) {      // translate the plugin content here    },
    translateThemeConfig({themeConfig, translationFiles}) {      // translate the site themeConfig here    },
    async getDefaultCodeTranslationMessages() {      // return default theme translations here    },  };};