diff --git a/website/docs/api/plugins/plugin-client-redirects.md b/website/docs/api/plugins/plugin-client-redirects.md index fca62c4555..3b881f5881 100644 --- a/website/docs/api/plugins/plugin-client-redirects.md +++ b/website/docs/api/plugins/plugin-client-redirects.md @@ -5,13 +5,15 @@ title: '📦 plugin-client-redirects' slug: '/api/plugins/@docusaurus/plugin-client-redirects' --- +import APITable from '@site/src/components/APITable'; + Docusaurus Plugin to generate **client-side redirects**. -This plugin will write additional HTML pages to your static site, that redirects the user to your existing Docusaurus pages with JavaScript. +This plugin will write additional HTML pages to your static site that redirect the user to your existing Docusaurus pages with JavaScript. -:::note +:::caution production only -This plugin only create redirects for the production build. +This plugin is always inactive in development and **only active in production** because it works on the build output. ::: @@ -31,99 +33,65 @@ npm install --save @docusaurus/plugin-client-redirects ## Configuration {#configuration} -Main usecase: you have `/myDocusaurusPage`, and you want to redirect to this page from `/myDocusaurusPage.html`: +Accepted fields: -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-client-redirects', - { - fromExtensions: ['html'], - }, - ], - ], + + +| Option | Type | Default | Description | +| --- | --- | --- | --- | +| `fromExtensions` | `string[]` | `[]` | The extensions to be removed from the route after redirecting. | +| `toExtensions` | `string[]` | `[]` | The extensions to be appended to the route after redirecting. | +| `redirects` | `RedirectRule[]` | `[]` | The list of redirect rules. | +| `createRedirects` | `CreateRedirectsFn` | `undefined` | A callback to create a redirect rule. | + + + +```ts +type RedirectRule = { + to: string; + from: string | string[]; }; + +type CreateRedirectsFn = (path: string) => string[] | string | null | undefined; ``` -Second usecase: you have `/myDocusaurusPage.html`, and you want to redirect to this page from `/myDocusaurusPage`. - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-client-redirects', - { - toExtensions: ['html'], - }, - ], - ], -}; -``` - -For custom redirect logic, provide your own `createRedirects` function. - -Let's imagine you change the url of an existing page, you might want to make sure the old url still works: +### Example configuration {#ex-config} + +Here's an example configuration: ```js title="docusaurus.config.js" module.exports = { plugins: [ [ '@docusaurus/plugin-client-redirects', + // highlight-start { + fromExtensions: ['html', 'htm'], // /myPage.html -> /myPage + toExtensions: ['exe', 'zip'], // /myAsset -> /myAsset.zip (if latter exists) redirects: [ + // /docs/oldDoc -> /docs/newDoc { - to: '/docs/newDocPath', // string - from: ['/docs/oldDocPathFrom2019', '/docs/legacyDocPathFrom2016'], // string | string[] + to: '/docs/newDoc', + from: '/docs/oldDoc', + }, + // Redirect from multiple old paths to the new path + { + to: '/docs/newDoc2', + from: ['/docs/oldDocFrom2019', '/docs/legacyDocFrom2016'], }, ], - }, - ], - ], -}; -``` - -It's possible to use a function to create the redirects for each existing path: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-client-redirects', - { - createRedirects: function (existingPath) { - if (existingPath === '/docs/newDocPath') { - return ['/docs/oldDocPathFrom2019', '/docs/legacyDocPathFrom2016']; // string | string[] - } - }, - }, - ], - ], -}; -``` - -Finally, it's possible to use all options at the same time: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-client-redirects', - { - fromExtensions: ['html', 'htm'], - toExtensions: ['exe', 'zip'], - redirects: [ - { - to: '/docs/newDocPath', - from: '/docs/oldDocPath', - }, - ], - createRedirects: function (existingPath) { - if (existingPath === '/docs/newDocPath2') { - return ['/docs/oldDocPath2']; + createRedirects(existingPath) { + if (existingPath.includes('/community')) { + // Redirect from /docs/team/X to /community/X and /docs/support/X to /community/X + return [ + existingPath.replace('/community', '/docs/team'), + existingPath.replace('/community', '/docs/support'), + ]; } + return undefined; // Return a falsy value: no redirect created }, }, + // highlight-end ], ], }; diff --git a/website/docs/api/plugins/plugin-content-blog.md b/website/docs/api/plugins/plugin-content-blog.md index bae9d3db81..de7c9bc7f3 100644 --- a/website/docs/api/plugins/plugin-content-blog.md +++ b/website/docs/api/plugins/plugin-content-blog.md @@ -9,6 +9,12 @@ import APITable from '@site/src/components/APITable'; Provides the [Blog](blog.mdx) feature and is the default blog plugin for Docusaurus. +:::caution some features production only + +The [feed feature](../../blog.mdx#feed) works by extracting the build output, and is **only active in production**. + +::: + ## Installation {#installation} ```bash npm2yarn @@ -94,27 +100,27 @@ type ReadingTimeFunctionOption = (params: { type FeedType = 'rss' | 'atom' | 'json'; ``` -## Example configuration {#ex-config} +### Example configuration {#ex-config} -Here's an example configuration object. - -You can provide it as [preset options](#ex-config-preset) or [plugin options](#ex-config-plugin). +You can configure this plugin through preset options or plugin options. :::tip -Most Docusaurus users configure this plugin through the [preset options](#ex-config-preset). +Most Docusaurus users configure this plugin through the preset options. ::: -```js +```js config-tabs +// preset option name: blog +// plugin name: @docusaurus/plugin-content-blog + const config = { path: 'blog', // Simple use-case: string editUrl // editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/', // Advanced use-case: functional editUrl - editUrl: ({locale, blogDirPath, blogPath, permalink}) => { - return `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`; - }, + editUrl: ({locale, blogDirPath, blogPath, permalink}) => + `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`, editLocalizedFiles: false, blogTitle: 'Blog title', blogDescription: 'Blog', @@ -149,48 +155,6 @@ const config = { }; ``` -### Preset options {#ex-config-preset} - -If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): - -```js title="docusaurus.config.js" -module.exports = { - presets: [ - [ - '@docusaurus/preset-classic', - { - // highlight-start - blog: { - path: 'blog', - // ... configuration object here - }, - // highlight-end - }, - ], - ], -}; -``` - -### Plugin options {#ex-config-plugin} - -If you are using a standalone plugin, provide options directly to the plugin: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-content-blog', - // highlight-start - { - path: 'blog', - // ... configuration object here - }, - // highlight-end - ], - ], -}; -``` - ## Markdown front matter {#markdown-front-matter} Markdown documents can use the following Markdown front matter metadata fields, enclosed by a line `---` on either side. diff --git a/website/docs/api/plugins/plugin-content-docs.md b/website/docs/api/plugins/plugin-content-docs.md index 87d5348d85..b50e9a3b7f 100644 --- a/website/docs/api/plugins/plugin-content-docs.md +++ b/website/docs/api/plugins/plugin-content-docs.md @@ -19,7 +19,7 @@ npm install --save @docusaurus/plugin-content-docs If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. -You can configure this plugin through the [preset options](#ex-config-preset). +You can configure this plugin through the preset options. ::: @@ -103,19 +103,20 @@ type Versions = Record< >; ``` -## Example configuration {#ex-config} +### Example configuration {#ex-config} -Here's an example configuration object. - -You can provide it as [preset options](#ex-config-preset) or [plugin options](#ex-config-plugin). +You can configure this plugin through preset options or plugin options. :::tip -Most Docusaurus users configure this plugin through the [preset options](#ex-config-preset). +Most Docusaurus users configure this plugin through the preset options. ::: -```js +```js config-tabs +// preset option name: docs +// plugin name: @docusaurus/plugin-content-docs + const config = { path: 'docs', // Simple use-case: string editUrl @@ -134,7 +135,7 @@ const config = { '**/__tests__/**', ], sidebarPath: 'sidebars.js', - sidebarItemsGenerator: async function ({ + async sidebarItemsGenerator({ defaultSidebarItemsGenerator, numberPrefixParser, item, @@ -154,7 +155,7 @@ const config = { }, ]; }, - numberPrefixParser: function (filename) { + numberPrefixParser(filename) { // Implement your own logic to extract a potential number prefix const numberPrefix = findNumberPrefix(filename); // Prefix found: return it with the cleaned filename @@ -194,48 +195,6 @@ const config = { }; ``` -### Preset options {#ex-config-preset} - -If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): - -```js title="docusaurus.config.js" -module.exports = { - presets: [ - [ - '@docusaurus/preset-classic', - { - // highlight-start - docs: { - path: 'docs', - // ... configuration object here - }, - // highlight-end - }, - ], - ], -}; -``` - -### Plugin options {#ex-config-plugin} - -If you are using a standalone plugin, provide options directly to the plugin: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-content-docs', - // highlight-start - { - path: 'docs', - // ... configuration object here - }, - // highlight-end - ], - ], -}; -``` - ## Markdown front matter {#markdown-front-matter} Markdown documents can use the following Markdown front matter metadata fields, enclosed by a line `---` on either side. diff --git a/website/docs/api/plugins/plugin-content-pages.md b/website/docs/api/plugins/plugin-content-pages.md index f2c4bc7c92..9020b539b6 100644 --- a/website/docs/api/plugins/plugin-content-pages.md +++ b/website/docs/api/plugins/plugin-content-pages.md @@ -19,7 +19,7 @@ npm install --save @docusaurus/plugin-content-pages If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. -You can configure this plugin through the [preset options](#ex-config-preset). +You can configure this plugin through the preset options. ::: @@ -43,19 +43,20 @@ Accepted fields: -## Example configuration {#ex-config} +### Example configuration {#ex-config} -Here's an example configuration object. - -You can provide it as [preset options](#ex-config-preset) or [plugin options](#ex-config-plugin). +You can configure this plugin through preset options or plugin options. :::tip -Most Docusaurus users configure this plugin through the [preset options](#ex-config-preset). +Most Docusaurus users configure this plugin through the preset options. ::: -```js +```js config-tabs +// preset option name: pages +// plugin name: @docusaurus/plugin-content-pages + const config = { path: 'src/pages', routeBasePath: '', @@ -74,48 +75,6 @@ const config = { }; ``` -### Preset options {#ex-config-preset} - -If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): - -```js title="docusaurus.config.js" -module.exports = { - presets: [ - [ - '@docusaurus/preset-classic', - { - // highlight-start - pages: { - path: 'src/pages', - // ... configuration object here - }, - // highlight-end - }, - ], - ], -}; -``` - -### Plugin options {#ex-config-plugin} - -If you are using a standalone plugin, provide options directly to the plugin: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-content-pages', - // highlight-start - { - path: 'src/pages', - // ... configuration object here - }, - // highlight-end - ], - ], -}; -``` - ## i18n {#i18n} Read the [i18n introduction](../../i18n/i18n-introduction.md) first. diff --git a/website/docs/api/plugins/plugin-debug.md b/website/docs/api/plugins/plugin-debug.md index 43f57305b5..a05c4f72df 100644 --- a/website/docs/api/plugins/plugin-debug.md +++ b/website/docs/api/plugins/plugin-debug.md @@ -5,15 +5,37 @@ title: '📦 plugin-debug' slug: '/api/plugins/@docusaurus/plugin-debug' --- +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +``` + The debug plugin will display useful debug information at [http://localhost:3000/\_\_docusaurus/debug](http://localhost:3000/__docusaurus/debug). It is mostly useful for plugin authors, that will be able to inspect more easily the content of the `.docusaurus` folder (like the creates routes), but also be able to inspect data structures that are never written to disk, like the plugin data loaded through the `contentLoaded` lifecycle. +:::info + +If you use the plugin via the classic preset, the preset will **enable the plugin in development and disable it in production** by default (`debug: undefined`) to avoid exposing potentially sensitive information. You can use `debug: true` to always enable it or `debug: false` to always disable it. + +If you use a standalone plugin, you may need to achieve the same effect by checking the environment: + +```js title="docusaurus.config.js" +module.exports = { + plugins: [ + // highlight-next-line + process.env.NODE_ENV === 'production' && '@docusaurus/plugin-debug', + ].filter(Boolean), +}; +``` + +::: + :::note If you report a bug, we will probably ask you to have this plugin turned on in the production, so that we can inspect your deployment config more easily. -If you don't have any sensitive information, you can keep it on in production [like we do](http://docusaurus.io/__docusaurus/debug). +If you don't have any sensitive information, you can keep it on in production [like we do](/__docusaurus/debug). ::: @@ -25,16 +47,56 @@ npm install --save @docusaurus/plugin-debug :::tip -If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. You can also configure it through the [classic preset options](presets.md#docusauruspreset-classic) instead of doing it like below. +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. -By default, it's enabled in dev, and disabled in prod, to avoid exposing potentially sensitive information. +You can configure this plugin through the preset options. ::: ## Configuration {#configuration} +This plugin currently has no options. + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + + + + +If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): + ```js title="docusaurus.config.js" module.exports = { + presets: [ + [ + '@docusaurus/preset-classic', + { + // highlight-next-line + debug: true, // This will enable the plugin in production + }, + ], + ], +}; +``` + + + + +If you are using a standalone plugin, provide options directly to the plugin: + +```js title="docusaurus.config.js" +module.exports = { + // highlight-next-line plugins: ['@docusaurus/plugin-debug'], }; ``` + + + diff --git a/website/docs/api/plugins/plugin-google-analytics.md b/website/docs/api/plugins/plugin-google-analytics.md index c38a45394b..d74af79198 100644 --- a/website/docs/api/plugins/plugin-google-analytics.md +++ b/website/docs/api/plugins/plugin-google-analytics.md @@ -5,8 +5,16 @@ title: '📦 plugin-google-analytics' slug: '/api/plugins/@docusaurus/plugin-google-analytics' --- +import APITable from '@site/src/components/APITable'; + The default [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/) plugin. It is a JavaScript library for measuring how users interact with your website **in the production build**. If you are using Google Analytics 4 you might need to consider using [plugin-google-gtag](./plugin-google-gtag.md) instead. +:::caution production only + +This plugin is always inactive in development and **only active in production** to avoid polluting the analytics statistics. + +::: + ## Installation {#installation} ```bash npm2yarn @@ -15,7 +23,9 @@ npm install --save @docusaurus/plugin-google-analytics :::tip -If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the preset options. ::: @@ -23,72 +33,31 @@ If you have installed `@docusaurus/preset-classic`, you don't need to install it Accepted fields: - + | Name | Type | Default | Description | | --- | --- | --- | --- | | `trackingID` | `string` | **Required** | The tracking ID of your analytics service. | | `anonymizeIP` | `boolean` | `false` | Whether the IP should be anonymized when sending requests. | - + -## Example configuration {#ex-config} +### Example configuration {#ex-config} -Here's an example configuration object. - -You can provide it as [preset options](#ex-config-preset) or [plugin options](#ex-config-plugin). +You can configure this plugin through preset options or plugin options. :::tip -Most Docusaurus users configure this plugin through the [preset options](#ex-config-preset). +Most Docusaurus users configure this plugin through the preset options. ::: -```js +```js config-tabs +// preset option name: googleAnalytics +// plugin name: @docusaurus/plugin-google-analytics + const config = { trackingID: 'UA-141789564-1', anonymizeIP: true, }; ``` - -### Preset options {#ex-config-preset} - -If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): - -```js title="docusaurus.config.js" -module.exports = { - presets: [ - [ - '@docusaurus/preset-classic', - { - // highlight-start - googleAnalytics: { - trackingID: 'UA-141789564-1', - anonymizeIP: true, - }, - // highlight-end - }, - ], - ], -}; -``` - -### Plugin options {#ex-config-plugin} - -If you are using a standalone plugin, provide options directly to the plugin: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-google-analytics', - // highlight-start - { - trackingID: 'UA-141789564-1', - anonymizeIP: true, - }, - // highlight-end - ], - ], -}; -``` diff --git a/website/docs/api/plugins/plugin-google-gtag.md b/website/docs/api/plugins/plugin-google-gtag.md index 8050514fb3..46395e0bf3 100644 --- a/website/docs/api/plugins/plugin-google-gtag.md +++ b/website/docs/api/plugins/plugin-google-gtag.md @@ -5,7 +5,9 @@ title: '📦 plugin-google-gtag' slug: '/api/plugins/@docusaurus/plugin-google-gtag' --- -The default [Global Site Tag (gtag.js)](https://developers.google.com/analytics/devguides/collection/gtagjs/) plugin. It is a JavaScript tagging framework and API that allows you to send event data to Google Analytics, Google Ads, and Google Marketing Platform, **in the production build**. This section describes how to configure a Docusaurus site to enable global site tag for Google Analytics. +import APITable from '@site/src/components/APITable'; + +The default [Global Site Tag (gtag.js)](https://developers.google.com/analytics/devguides/collection/gtagjs/) plugin. It is a JavaScript tagging framework and API that allows you to send event data to Google Analytics, Google Ads, and Google Marketing Platform. This section describes how to configure a Docusaurus site to enable global site tag for Google Analytics. :::tip @@ -13,6 +15,12 @@ You can use [Google's Tag Assistant](https://tagassistant.google.com/) tool to c ::: +:::caution production only + +This plugin is always inactive in development and **only active in production** to avoid polluting the analytics statistics. + +::: + ## Installation {#installation} ```bash npm2yarn @@ -21,7 +29,9 @@ npm install --save @docusaurus/plugin-google-gtag :::tip -If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the preset options. ::: @@ -29,72 +39,31 @@ If you have installed `@docusaurus/preset-classic`, you don't need to install it Accepted fields: - + | Name | Type | Default | Description | | --- | --- | --- | --- | | `trackingID` | `string` | **Required** | The tracking ID of your gtag service. | | `anonymizeIP` | `boolean` | `false` | Whether the IP should be anonymized when sending requests. | - + -## Example configuration {#ex-config} +### Example configuration {#ex-config} -Here's an example configuration object. - -You can provide it as [preset options](#ex-config-preset) or [plugin options](#ex-config-plugin). +You can configure this plugin through preset options or plugin options. :::tip -Most Docusaurus users configure this plugin through the [preset options](#ex-config-preset). +Most Docusaurus users configure this plugin through the preset options. ::: -```js +```js config-tabs +// preset option name: gtag +// plugin name: @docusaurus/plugin-google-gtag + const config = { trackingID: '141789564', anonymizeIP: true, }; ``` - -### Preset options {#ex-config-preset} - -If you use a preset, configure this plugin through the [preset options](presets.md#docusauruspreset-classic): - -```js title="docusaurus.config.js" -module.exports = { - presets: [ - [ - '@docusaurus/preset-classic', - { - // highlight-start - gtag: { - trackingID: '141789564', - anonymizeIP: true, - }, - // highlight-end - }, - ], - ], -}; -``` - -### Plugin options {#ex-config-plugin} - -If you are using a standalone plugin, provide options directly to the plugin: - -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-google-gtag', - // highlight-start - { - trackingID: '141789564', - anonymizeIP: true, - }, - // highlight-end - ], - ], -}; -``` diff --git a/website/docs/api/plugins/plugin-ideal-image.md b/website/docs/api/plugins/plugin-ideal-image.md index 005d9c8f55..db40b29d7d 100644 --- a/website/docs/api/plugins/plugin-ideal-image.md +++ b/website/docs/api/plugins/plugin-ideal-image.md @@ -9,6 +9,12 @@ import APITable from '@site/src/components/APITable'; Docusaurus Plugin to generate an almost ideal image (responsive, lazy-loading, and low quality placeholder). +:::info + +By default, the plugin is **inactive in development** so you could always view full-scale images. If you want to debug the ideal image behavior, you could set the [`disableInDev`](#disableInDev) option to `false`. + +::: + ## Installation {#installation} ```bash npm2yarn @@ -49,7 +55,7 @@ Accepted fields: -## Example configuration {#ex-config} +### Example configuration {#ex-config} Here's an example configuration: diff --git a/website/docs/api/plugins/plugin-sitemap.md b/website/docs/api/plugins/plugin-sitemap.md index 5e61a00b76..3d56a8b7b2 100644 --- a/website/docs/api/plugins/plugin-sitemap.md +++ b/website/docs/api/plugins/plugin-sitemap.md @@ -5,7 +5,15 @@ title: '📦 plugin-sitemap' slug: '/api/plugins/@docusaurus/plugin-sitemap' --- -This plugin creates sitemap for your site so that search engine crawlers can crawl your site more accurately. +import APITable from '@site/src/components/APITable'; + +This plugin creates sitemaps for your site so that search engine crawlers can crawl your site more accurately. + +:::caution production only + +This plugin is always inactive in development and **only active in production** because it works on the build output. + +::: ## Installation {#installation} @@ -15,23 +23,41 @@ npm install --save @docusaurus/plugin-sitemap :::tip -If you have installed `@docusaurus/preset-classic`, you don't need to install it as a dependency. You can also configure it through the [classic preset options](presets.md#docusauruspreset-classic) instead of doing it like below. +If you use the preset `@docusaurus/preset-classic`, you don't need to install this plugin as a dependency. + +You can configure this plugin through the [preset options](#ex-config-preset). ::: ## Configuration {#configuration} -```js title="docusaurus.config.js" -module.exports = { - plugins: [ - [ - '@docusaurus/plugin-sitemap', - { - changefreq: 'weekly', - priority: 0.5, - trailingSlash: false, - }, - ], - ], +Accepted fields: + + + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `changefreq` | `string` | `'weekly'` | See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions) | +| `priority` | `number` | `0.5` | See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions) | + + + +### Example configuration {#ex-config} + +You can configure this plugin through preset options or plugin options. + +:::tip + +Most Docusaurus users configure this plugin through the preset options. + +::: + +```js config-tabs +// preset option name: sitemap +// plugin name: @docusaurus/plugin-sitemap + +const config = { + changefreq: 'weekly', + priority: 0.5, }; ``` diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 1afca6fb2c..8a9d388209 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -14,6 +14,7 @@ const VersionsArchived = require('./versionsArchived.json'); const {dogfoodingPluginInstances} = require('./_dogfooding/dogfooding.config'); const FeatureRequestsPlugin = require('./src/featureRequests/FeatureRequestsPlugin'); const npm2yarn = require('@docusaurus/remark-plugin-npm2yarn'); +const configTabs = require('./src/remark/configTabs'); // eslint-disable-next-line import/no-extraneous-dependencies const lightTheme = require('prism-react-renderer/themes/github'); // eslint-disable-next-line import/no-extraneous-dependencies @@ -267,7 +268,7 @@ const config = { }, showLastUpdateAuthor: true, showLastUpdateTime: true, - remarkPlugins: [math, [npm2yarn, {sync: true}]], + remarkPlugins: [math, [npm2yarn, {sync: true}], configTabs], rehypePlugins: [katex], disableVersioning: isVersioningDisabled, lastVersion: isDev || isDeployPreview ? 'current' : undefined, diff --git a/website/package.json b/website/package.json index 229ab97443..fe12088a58 100644 --- a/website/package.json +++ b/website/package.json @@ -51,6 +51,7 @@ "react-popper": "^2.2.5", "rehype-katex": "^5.0.0", "remark-math": "^3.0.1", + "unist-util-visit": "^2.0.2", "workbox-routing": "^5.0.0", "workbox-strategies": "^5.0.0" }, diff --git a/website/src/remark/configTabs.js b/website/src/remark/configTabs.js new file mode 100644 index 0000000000..ad36348439 --- /dev/null +++ b/website/src/remark/configTabs.js @@ -0,0 +1,158 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const visit = require('unist-util-visit'); + +/** + * Turns a "```js config-tabs" code block into a "plugin options" and a "preset options" tab + */ +const plugin = () => { + const transformer = (root) => { + let tabsImported = false; + let codeBlockImported = false; + let transformed = false; + visit(root, ['code', 'import'], (node, index, parent) => { + if (node.type === 'import') { + if (node.value.includes('@theme/Tabs')) { + tabsImported = true; + } else if (node.value.includes('@theme/CodeBlock')) { + codeBlockImported = true; + } + } else if (node.meta?.includes('config-tabs')) { + transformed = true; + const {value} = node; + const [presetMeta, pluginMeta] = value.split('\n'); + const { + groups: {presetOptionName}, + } = presetMeta.match( + /preset option name: (?[A-Za-z]+)/i, + ); + const { + groups: {pluginName}, + } = pluginMeta.match(/plugin name: (?[A-Za-z@/-]+)/i); + // Replace leading "const config = " and trailing semi + const config = value + .replace(presetMeta, '') + .replace(pluginMeta, '') + .trim() + .replace(/^.*?= /, '') + .replace(/;$/, '') + .replace(/`/g, '\\`') + .replace(/\$/g, '\\$'); + const newNodes = [ + { + type: 'jsx', + value: `\n`, + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: + 'If you use a preset, configure this plugin through the ', + }, + { + type: 'link', + title: null, + // TODO make this version-aware; maybe we need a useVersionedLink() hook + url: '/docs/presets#docusauruspreset-classic', + children: [ + { + type: 'text', + value: 'preset options', + }, + ], + }, + { + type: 'text', + value: ':', + }, + ], + }, + { + type: 'jsx', + value: ` +{\`module.exports = { + presets: [ + [ + '@docusaurus/preset-classic', + { + // highlight-start + ${presetOptionName}: ${config + .split('\n') + .map((line) => ` ${line}`) + .join('\n') + .trim()}, + // highlight-end + }, + ], + ], +};\`} +`, + }, + { + type: 'jsx', + value: '\n', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: + 'If you are using a standalone plugin, provide options directly to the plugin:', + }, + ], + }, + { + type: 'jsx', + value: ` +{\`module.exports = { + plugins: [ + [ + '${pluginName}', + // highlight-start + ${config + .split('\n') + .map((line) => ` ${line}`) + .join('\n') + .trim()}, + // highlight-end + ], + ], +};\`} +`, + }, + { + type: 'jsx', + value: '\n', + }, + ]; + parent.children.splice(index, 1, ...newNodes); + } + }); + if (transformed) { + if (!tabsImported) { + root.children.unshift({ + type: 'import', + value: + "import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';", + }); + } + if (!codeBlockImported) { + root.children.unshift({ + type: 'import', + value: "import CodeBlock from '@theme/CodeBlock';", + }); + } + } + }; + return transformer; +}; + +module.exports = plugin;