mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-30 01:17:07 +02:00
Merge branch 'main' into ozaki/showcase
This commit is contained in:
commit
01657b0744
249 changed files with 24910 additions and 3445 deletions
|
@ -333,6 +333,20 @@ test
|
|||
|
||||
::::
|
||||
|
||||
```mdx-code-block
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
export function AdmonitionWithoutHeading(props) {
|
||||
return (
|
||||
<Admonition {...props} type="info" icon={null} title={null}>
|
||||
Admonition content without heading
|
||||
</Admonition>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
<AdmonitionWithoutHeading />
|
||||
|
||||
## Linking
|
||||
|
||||
This is a test page to see if Docusaurus Markdown features are working properly
|
||||
|
|
BIN
website/blog/releases/3.3/img/social-card.png
Normal file
BIN
website/blog/releases/3.3/img/social-card.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
110
website/blog/releases/3.3/index.mdx
Normal file
110
website/blog/releases/3.3/index.mdx
Normal file
|
@ -0,0 +1,110 @@
|
|||
---
|
||||
title: Docusaurus 3.3
|
||||
authors: [slorber]
|
||||
tags: [release]
|
||||
image: ./img/social-card.png
|
||||
date: 2024-05-03
|
||||
---
|
||||
|
||||
We are happy to announce **Docusaurus 3.3**.
|
||||
|
||||
Upgrading should be easy. Our [release process](/community/release-process) respects [Semantic Versioning](https://semver.org/). Minor versions do not include any breaking changes.
|
||||
|
||||

|
||||
|
||||
<!--truncate-->
|
||||
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
import IframeWindow from '@site/src/components/BrowserWindow/IframeWindow';
|
||||
|
||||
## Highlights
|
||||
|
||||
### Prepare for React 19
|
||||
|
||||
The React core team recently [released the first **React 19 beta**](https://react.dev/blog/2024/04/25/react-19). They also [published an upgrade guide and a ** React v18.3 release**](https://react.dev/blog/2024/04/25/react-19-upgrade-guide) with new warnings to help us identify issues **before upgrading to React 19**.
|
||||
|
||||
Docusaurus v3 depends on React `18.x`. When initializing a new Docusaurus sites, it will use that new React `18.3` release. It's also the case if you decide to upgrade your dependencies, or re-generate your package manager lockfile.
|
||||
|
||||
It turns out in its current state, **Docusaurus had a few of those extra warnings to fix**, notably this one immediately appearing on your dev console on any page load and navigation:
|
||||
|
||||
> Warning: LoadableComponent uses the legacy contextTypes API which is no longer supported and will be removed in the next major release. Use React.createContext() with static contextType instead.
|
||||
|
||||
In [#10079](https://github.com/facebook/docusaurus/pull/10079), we got Docusaurus ready for React 19. We fixed all the React 18.3 warnings we encountered. In case we missed any, don't hesitate to [**report new warnings**](https://github.com/facebook/docusaurus/issues/10099) if you see them, to us but also to other Docusaurus third-party plugin authors.
|
||||
|
||||
### `createSitemapItems`
|
||||
|
||||
In [#10083](https://github.com/facebook/docusaurus/pull/10083), we introduced a new flexible `createSitemapItems()` hook to the sitemap plugin. This enables users to create/filter/transform/enhance the sitemap items with their own custom logic.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
sitemap: {
|
||||
// highlight-start
|
||||
createSitemapItems: async ({
|
||||
defaultCreateSitemapItems,
|
||||
...params
|
||||
}) => {
|
||||
const items = await defaultCreateSitemapItems(params);
|
||||
return items.filter((item) => !item.url.includes('/tags/'));
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Pages plugin improvements
|
||||
|
||||
The Docusaurus [pages plugin](/docs/api/plugins/@docusaurus/plugin-content-pages) has historically been lagging behind the docs and blog plugins in terms of available feature.
|
||||
|
||||
In [#10032](https://github.com/facebook/docusaurus/pull/10032) we normalized the options available on each core content plugins by adding a few the missing page plugins APIs related to the edit url and the last update metadata displayed at the bottom on Markdown pages.
|
||||
|
||||
```js
|
||||
export default {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
pages: {
|
||||
// highlight-start
|
||||
editUrl:
|
||||
'https://github.com/facebook/docusaurus/tree/main/website/src/pages',
|
||||
editLocalizedFiles: true,
|
||||
showLastUpdateAuthor: true,
|
||||
showLastUpdateTime: true,
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
<IframeWindow url="/examples/markdownPageExample" />
|
||||
|
||||
:::note Only for Markdown pages
|
||||
|
||||
These new plugin options only apply to Markdown pages, and have no effect on React pages for which you have full control over the layout with JSX.
|
||||
|
||||
:::
|
||||
|
||||
## Other changes
|
||||
|
||||
Other notable changes include:
|
||||
|
||||
- [#10064](https://github.com/facebook/docusaurus/pull/10064): new site config option `siteConfig.markdown.anchors.maintainCase`
|
||||
- [#9767](https://github.com/facebook/docusaurus/pull/9767): new `docusaurus deploy --target-dir` option
|
||||
- [#10042](https://github.com/facebook/docusaurus/pull/10042): new (experimental) plugin API: `route.props`
|
||||
- [#10060](https://github.com/facebook/docusaurus/pull/10060): optimizes the App entrypoint, avoid useless re-renders on navigations
|
||||
- [#10080](https://github.com/facebook/docusaurus/pull/10080): `<Admonition>` component can render properly without heading/icon
|
||||
- [#10091](https://github.com/facebook/docusaurus/pull/10091): `<Tabs>` props can now override defaults
|
||||
- [#10090](https://github.com/facebook/docusaurus/pull/10090): `docusaurus serve` works better with a `/baseUrl/` pathname prefix
|
||||
- [#10070](https://github.com/facebook/docusaurus/pull/10070): add missing theme translations for `pt-BR`
|
||||
- [#10025](https://github.com/facebook/docusaurus/pull/10025): doc sidebar item label now impacts the doc pagination label
|
||||
|
||||
Check the **[3.3.0 changelog entry](/changelog/3.3.0)** for an exhaustive list of changes.
|
|
@ -18,6 +18,12 @@ Refer to the Getting Started [**Configuration**](../configuration.mdx) for examp
|
|||
|
||||
`docusaurus.config.js` contains configurations for your site and is placed in the root directory of your site.
|
||||
|
||||
:::note
|
||||
|
||||
With a [TypeScript](../typescript-support.mdx) Docusaurus codebase your config file may be called `docusaurus.config.ts`. The syntax is broadly identical to the `js` config file with the addition of types. You can see an example on the [Docusaurus Website](https://github.com/facebook/docusaurus/blob/main/website/docusaurus.config.ts) itself.
|
||||
|
||||
:::
|
||||
|
||||
This file is run in Node.js and should export a site configuration object, or a function that creates it.
|
||||
|
||||
The `docusaurus.config.js` file supports:
|
||||
|
@ -438,6 +444,10 @@ export type ParseFrontMatter = (params: {
|
|||
content: string;
|
||||
}>;
|
||||
|
||||
type MarkdownAnchorsConfig = {
|
||||
maintainCase: boolean;
|
||||
};
|
||||
|
||||
type MarkdownConfig = {
|
||||
format: 'mdx' | 'md' | 'detect';
|
||||
mermaid: boolean;
|
||||
|
@ -445,6 +455,7 @@ type MarkdownConfig = {
|
|||
parseFrontMatter?: ParseFrontMatter;
|
||||
mdx1Compat: MDX1CompatOptions;
|
||||
remarkRehypeOptions: object; // see https://github.com/remarkjs/remark-rehype#options
|
||||
anchors: MarkdownAnchorsConfig;
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -469,6 +480,9 @@ export default {
|
|||
admonitions: true,
|
||||
headingIds: true,
|
||||
},
|
||||
anchors: {
|
||||
maintainCase: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
@ -484,6 +498,7 @@ export default {
|
|||
| `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. |
|
||||
| `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. |
|
||||
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. |
|
||||
| `anchors` | `MarkdownAnchorsConfig` | `{maintainCase: false}` | Options to control the behavior of anchors generated from Markdown headings |
|
||||
| `remarkRehypeOptions` | `object` | `undefined` | Makes it possible to pass custom [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#options). |
|
||||
|
||||
```mdx-code-block
|
||||
|
|
|
@ -44,11 +44,24 @@ Accepted fields:
|
|||
| `priority` | `number \| null` | `0.5` | See [sitemap docs](https://www.sitemaps.org/protocol.html#xmlTagDefinitions) |
|
||||
| `ignorePatterns` | `string[]` | `[]` | A list of glob patterns; matching route paths will be filtered from the sitemap. Note that you may need to include the base URL in here. |
|
||||
| `filename` | `string` | `sitemap.xml` | The path to the created sitemap file, relative to the output directory. Useful if you have two plugin instances outputting two files. |
|
||||
| `createSitemapItems` | <code>[CreateSitemapItemsFn](#CreateSitemapItemsFn) \| undefined</code> | `undefined` | An optional function which can be used to transform and / or filter the items in the sitemap. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### Types {#types}
|
||||
|
||||
#### `CreateSitemapItemsFn` {#CreateSitemapItemsFn}
|
||||
|
||||
```ts
|
||||
type CreateSitemapItemsFn = (params: {
|
||||
siteConfig: DocusaurusConfig;
|
||||
routes: RouteConfig[];
|
||||
defaultCreateSitemapItems: CreateSitemapItemsFn;
|
||||
}) => Promise<SitemapItem[]>;
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
This plugin also respects some site config:
|
||||
|
@ -86,6 +99,11 @@ const config = {
|
|||
priority: 0.5,
|
||||
ignorePatterns: ['/tags/**'],
|
||||
filename: 'sitemap.xml',
|
||||
createSitemapItems: async (params) => {
|
||||
const {defaultCreateSitemapItems, ...rest} = params;
|
||||
const items = await defaultCreateSitemapItems(rest);
|
||||
return items.filter((item) => !item.url.includes('/page/'));
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
|
|
|
@ -161,6 +161,7 @@ import DocusaurusSvg from './docusaurus.svg';
|
|||
Docusaurus supports themed images: the `ThemedImage` component (included in the themes) allows you to switch the image source based on the current theme.
|
||||
|
||||
```jsx
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||
import ThemedImage from '@theme/ThemedImage';
|
||||
|
||||
<ThemedImage
|
||||
|
|
|
@ -350,7 +350,7 @@ Docusaurus also has an `#algolia` channel on [Discord](https://discordapp.com/in
|
|||
|
||||
Typesense is an [open source](https://github.com/typesense/typesense) instant-search engine that you can either:
|
||||
|
||||
- [Self-Host](https://typesense.org/docs/latest/guide/install-typesense.html#option-2-local-machine-self-hosting) on your own servers or
|
||||
- [Self-Host](https://typesense.org/docs/guide/install-typesense.html#option-2-local-machine-self-hosting) on your own servers or
|
||||
- Use the Managed [Typesense Cloud](https://cloud.typesense.org) service.
|
||||
|
||||
Similar to Algolia DocSearch, there are two components:
|
||||
|
@ -358,7 +358,7 @@ Similar to Algolia DocSearch, there are two components:
|
|||
- [typesense-docsearch-scraper](https://github.com/typesense/typesense-docsearch-scraper) - which scrapes your website and indexes the data in your Typesense cluster.
|
||||
- [docusaurus-theme-search-typesense](https://github.com/typesense/docusaurus-theme-search-typesense) - a search bar UI component to add to your website.
|
||||
|
||||
Read a step-by-step walk-through of how to [run typesense-docsearch-scraper here](https://typesense.org/docs/latest/guide/docsearch.html#step-1-set-up-docsearch-scraper) and how to [install the Search Bar in your Docusaurus Site here](https://typesense.org/docs/latest/guide/docsearch.html#option-a-docusaurus-powered-sites).
|
||||
Read a step-by-step walk-through of how to [run typesense-docsearch-scraper here](https://typesense.org/docs/guide/docsearch.html#step-1-set-up-docsearch-scraper) and how to [install the Search Bar in your Docusaurus Site here](https://typesense.org/docs/guide/docsearch.html#option-a-docusaurus-powered-sites).
|
||||
|
||||
## 👥 Using Local Search {#using-local-search}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ description: Customize your site's appearance through creating your own theme co
|
|||
|
||||
In this section, we will introduce how customization of layout is done in Docusaurus.
|
||||
|
||||
> Déja vu...?
|
||||
> Déjà vu...?
|
||||
|
||||
This section is similar to [Styling and Layout](./styling-layout.mdx), but this time, we will customize React components themselves, rather than what they look like. We will talk about a central concept in Docusaurus: **swizzling**, which allows **deeper site customizations**.
|
||||
|
||||
|
|
|
@ -39,15 +39,37 @@ const ArchivedVersionsDropdownItems = Object.entries(VersionsArchived).splice(
|
|||
|
||||
function isPrerelease(version: string) {
|
||||
return (
|
||||
version.includes('-') ||
|
||||
version.includes('alpha') ||
|
||||
version.includes('beta') ||
|
||||
version.includes('rc')
|
||||
);
|
||||
}
|
||||
|
||||
function getLastVersion() {
|
||||
const firstStableVersion = versions.find((version) => !isPrerelease(version));
|
||||
return firstStableVersion ?? versions[0];
|
||||
function getLastStableVersion() {
|
||||
const lastStableVersion = versions.find((version) => !isPrerelease(version));
|
||||
if (!lastStableVersion) {
|
||||
throw new Error('unexpected, no stable Docusaurus version?');
|
||||
}
|
||||
return lastStableVersion;
|
||||
}
|
||||
const announcedVersion = getAnnouncedVersion();
|
||||
|
||||
function getLastStableVersionTuple(): [string, string, string] {
|
||||
const lastStableVersion = getLastStableVersion();
|
||||
const parts = lastStableVersion.split('.');
|
||||
if (parts.length !== 3) {
|
||||
throw new Error(`Unexpected stable version name: ${lastStableVersion}`);
|
||||
}
|
||||
return [parts[0]!, parts[1]!, parts[2]!];
|
||||
}
|
||||
|
||||
// The version announced on the homepage hero and announcement banner
|
||||
// 3.3.2 => 3.3
|
||||
// 3.0.5 => 3.0
|
||||
function getAnnouncedVersion() {
|
||||
const [major, minor] = getLastStableVersionTuple();
|
||||
return `${major}.${minor}`;
|
||||
}
|
||||
|
||||
// This probably only makes sense for the alpha/beta/rc phase, temporary
|
||||
|
@ -228,6 +250,7 @@ export default async function createConfigAsync() {
|
|||
isDeployPreview,
|
||||
description:
|
||||
'An optimized site generator in React. Docusaurus helps you to move fast and write content. Build documentation websites, blogs, marketing pages, and more.',
|
||||
announcedVersion,
|
||||
},
|
||||
staticDirectories: [
|
||||
'static',
|
||||
|
@ -426,7 +449,7 @@ export default async function createConfigAsync() {
|
|||
isBranchDeploy ||
|
||||
isBuildFast
|
||||
? 'current'
|
||||
: getLastVersion(),
|
||||
: getLastStableVersion(),
|
||||
|
||||
onlyIncludeVersions: (() => {
|
||||
if (isBuildFast) {
|
||||
|
@ -517,9 +540,9 @@ export default async function createConfigAsync() {
|
|||
respectPrefersColorScheme: true,
|
||||
},
|
||||
announcementBar: {
|
||||
id: 'announcementBar-v3.2', // Increment on change
|
||||
id: `announcementBar-v${announcedVersion}`,
|
||||
// content: `⭐️ If you like Docusaurus, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/facebook/docusaurus">GitHub</a> and follow us on <a target="_blank" rel="noopener noreferrer" href="https://twitter.com/docusaurus">Twitter ${TwitterSvg}</a>`,
|
||||
content: `🎉️ <b><a target="_blank" href="https://docusaurus.io/blog/releases/3.2">Docusaurus v3.2</a> is out!</b> 🥳️`,
|
||||
content: `🎉️ <b><a target="_blank" href="https://docusaurus.io/blog/releases/${announcedVersion}">Docusaurus v${announcedVersion}</a> is out!</b> 🥳️`,
|
||||
},
|
||||
prism: {
|
||||
additionalLanguages: [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "website",
|
||||
"version": "3.2.1",
|
||||
"version": "3.3.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
|
@ -36,19 +36,19 @@
|
|||
"dependencies": {
|
||||
"@crowdin/cli": "^3.13.0",
|
||||
"@crowdin/crowdin-api-client": "^1.29.5",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/plugin-client-redirects": "3.2.1",
|
||||
"@docusaurus/plugin-ideal-image": "3.2.1",
|
||||
"@docusaurus/plugin-pwa": "3.2.1",
|
||||
"@docusaurus/preset-classic": "3.2.1",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "3.2.1",
|
||||
"@docusaurus/theme-classic": "3.2.1",
|
||||
"@docusaurus/theme-common": "3.2.1",
|
||||
"@docusaurus/theme-live-codeblock": "3.2.1",
|
||||
"@docusaurus/theme-mermaid": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/core": "3.3.2",
|
||||
"@docusaurus/logger": "3.3.2",
|
||||
"@docusaurus/plugin-client-redirects": "3.3.2",
|
||||
"@docusaurus/plugin-ideal-image": "3.3.2",
|
||||
"@docusaurus/plugin-pwa": "3.3.2",
|
||||
"@docusaurus/preset-classic": "3.3.2",
|
||||
"@docusaurus/remark-plugin-npm2yarn": "3.3.2",
|
||||
"@docusaurus/theme-classic": "3.3.2",
|
||||
"@docusaurus/theme-common": "3.3.2",
|
||||
"@docusaurus/theme-live-codeblock": "3.3.2",
|
||||
"@docusaurus/theme-mermaid": "3.3.2",
|
||||
"@docusaurus/utils": "3.3.2",
|
||||
"@docusaurus/utils-common": "3.3.2",
|
||||
"@swc/core": "1.2.197",
|
||||
"clsx": "^2.0.0",
|
||||
"color": "^4.2.3",
|
||||
|
@ -81,8 +81,8 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/eslint-plugin": "3.2.1",
|
||||
"@docusaurus/tsconfig": "3.2.1",
|
||||
"@docusaurus/eslint-plugin": "3.3.2",
|
||||
"@docusaurus/tsconfig": "3.3.2",
|
||||
"@types/color": "^3.0.4",
|
||||
"@types/jest": "^29.5.3",
|
||||
"cross-env": "^7.0.3",
|
||||
|
|
|
@ -203,29 +203,21 @@ function FeaturesContainer() {
|
|||
}
|
||||
|
||||
function TopBanner() {
|
||||
/* TODO restore Ukraine banner after launch
|
||||
<Translate
|
||||
id="homepage.banner"
|
||||
values={{
|
||||
link: (
|
||||
<Link to="https://opensource.facebook.com/support-ukraine">
|
||||
<Translate id="homepage.banner.link">
|
||||
Help Provide Humanitarian Aid to Ukraine
|
||||
</Translate>
|
||||
</Link>
|
||||
),
|
||||
}}>
|
||||
{'Support Ukraine 🇺🇦 {link}.'}
|
||||
</Translate>
|
||||
*/
|
||||
// TODO We should be able to strongly type customFields
|
||||
// Refactor to use a CustomFields interface + TS declaration merging
|
||||
const announcedVersion = useDocusaurusContext().siteConfig.customFields
|
||||
?.announcedVersion as string;
|
||||
|
||||
return (
|
||||
<div className={styles.topBanner}>
|
||||
<div className={styles.topBannerTitle}>
|
||||
{'🎉\xa0'}
|
||||
<Link to="/blog/releases/3.2" className={styles.topBannerTitleText}>
|
||||
<Link
|
||||
to={`/blog/releases/${announcedVersion}`}
|
||||
className={styles.topBannerTitleText}>
|
||||
<Translate
|
||||
id="homepage.banner.launch.newVersion"
|
||||
values={{newVersion: '3.2'}}>
|
||||
values={{newVersion: announcedVersion}}>
|
||||
{'Docusaurus\xa0{newVersion} is\xa0out!️'}
|
||||
</Translate>
|
||||
</Link>
|
||||
|
|
BIN
website/static/katex/fonts/KaTeX_AMS-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_AMS-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_AMS-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_AMS-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Bold.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Bold.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Bold.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Caligraphic-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Fraktur-Bold.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Fraktur-Bold.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Fraktur-Bold.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Fraktur-Bold.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Fraktur-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Fraktur-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Fraktur-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Fraktur-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Bold.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Bold.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Bold.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Bold.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-BoldItalic.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-BoldItalic.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-BoldItalic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Italic.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Italic.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Italic.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Italic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Main-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Main-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Math-BoldItalic.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Math-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Math-BoldItalic.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Math-BoldItalic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Math-Italic.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Math-Italic.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Math-Italic.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Math-Italic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Bold.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Bold.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Bold.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Bold.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Italic.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Italic.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Italic.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Italic.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_SansSerif-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_SansSerif-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Script-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Script-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Script-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Script-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size1-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Size1-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size1-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Size1-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size2-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Size2-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size2-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Size2-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size3-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Size3-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size3-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Size3-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size4-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Size4-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Size4-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Size4-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Typewriter-Regular.ttf
Normal file
BIN
website/static/katex/fonts/KaTeX_Typewriter-Regular.ttf
Normal file
Binary file not shown.
BIN
website/static/katex/fonts/KaTeX_Typewriter-Regular.woff
Normal file
BIN
website/static/katex/fonts/KaTeX_Typewriter-Regular.woff
Normal file
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
description: How Docusaurus works to build your app
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
```mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Zoom from 'react-medium-image-zoom';
|
||||
```
|
||||
|
||||
<Zoom>
|
||||
|
||||

|
||||
|
||||
</Zoom>
|
||||
|
||||
This diagram shows how Docusaurus works to build your app. Plugins each collect their content and emit JSON data; themes provide layout components which receive the JSON data as route modules. The bundler bundles all the components and emits a server bundle and a client bundle.
|
||||
|
||||
Although you (either plugin authors or site creators) are writing JavaScript all the time, bear in mind that the JS is actually run in different environments:
|
||||
|
||||
- All plugin lifecycle methods are run in Node. Therefore, until we support ES Modules in our codebase, plugin source code must be provided as ES modules that can be imported, or CommonJS that can be `require`'d.
|
||||
- The theme code is built with Webpack. They can be provided as ESM—following React conventions.
|
||||
|
||||
Plugin code and theme code never directly import each other: they only communicate through protocols (in our case, through JSON temp files and calls to `addRoute`). A useful mental model is to imagine that the plugins are not written in JavaScript, but in another language like Rust. The only way to interact with plugins for the user is through `docusaurus.config.js`, which itself is run in Node (hence you can use `require` and pass callbacks as plugin options).
|
||||
|
||||
During bundling, the config file itself is serialized and bundled, allowing the theme to access config options like `themeConfig` or `baseUrl` through [`useDocusaurusContext()`](../docusaurus-core.mdx#useDocusaurusContext). However, the `siteConfig` object only contains **serializable values** (values that are preserved after `JSON.stringify()`). Functions, regexes, etc. would be lost on the client side. The `themeConfig` is designed to be entirely serializable.
|
184
website/versioned_docs/version-3.3.2/advanced/client.mdx
Normal file
184
website/versioned_docs/version-3.3.2/advanced/client.mdx
Normal file
|
@ -0,0 +1,184 @@
|
|||
---
|
||||
description: How the Docusaurus client is structured
|
||||
---
|
||||
|
||||
# Client architecture
|
||||
|
||||
## Theme aliases {#theme-aliases}
|
||||
|
||||
A theme works by exporting a set of components, e.g. `Navbar`, `Layout`, `Footer`, to render the data passed down from plugins. Docusaurus and users use these components by importing them using the `@theme` webpack alias:
|
||||
|
||||
```js
|
||||
import Navbar from '@theme/Navbar';
|
||||
```
|
||||
|
||||
The alias `@theme` can refer to a few directories, in the following priority:
|
||||
|
||||
1. A user's `website/src/theme` directory, which is a special directory that has the higher precedence.
|
||||
2. A Docusaurus theme package's `theme` directory.
|
||||
3. Fallback components provided by Docusaurus core (usually not needed).
|
||||
|
||||
This is called a _layered architecture_: a higher-priority layer providing the component would shadow a lower-priority layer, making swizzling possible. Given the following structure:
|
||||
|
||||
```
|
||||
website
|
||||
├── node_modules
|
||||
│ └── @docusaurus/theme-classic
|
||||
│ └── theme
|
||||
│ └── Navbar.js
|
||||
└── src
|
||||
└── theme
|
||||
└── Navbar.js
|
||||
```
|
||||
|
||||
`website/src/theme/Navbar.js` takes precedence whenever `@theme/Navbar` is imported. This behavior is called component swizzling. If you are familiar with Objective C where a function's implementation can be swapped during runtime, it's the exact same concept here with changing the target `@theme/Navbar` is pointing to!
|
||||
|
||||
We already talked about how the "userland theme" in `src/theme` can re-use a theme component through the [`@theme-original`](../swizzling.mdx#wrapping) alias. One theme package can also wrap a component from another theme, by importing the component from the initial theme, using the `@theme-init` import.
|
||||
|
||||
Here's an example of using this feature to enhance the default theme `CodeBlock` component with a `react-live` playground feature.
|
||||
|
||||
```js
|
||||
import InitialCodeBlock from '@theme-init/CodeBlock';
|
||||
import React from 'react';
|
||||
|
||||
export default function CodeBlock(props) {
|
||||
return props.live ? (
|
||||
<ReactLivePlayground {...props} />
|
||||
) : (
|
||||
<InitialCodeBlock {...props} />
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Check the code of `@docusaurus/theme-live-codeblock` for details.
|
||||
|
||||
:::warning
|
||||
|
||||
Unless you want to publish a re-usable "theme enhancer" (like `@docusaurus/theme-live-codeblock`), you likely don't need `@theme-init`.
|
||||
|
||||
:::
|
||||
|
||||
It can be quite hard to wrap your mind around these aliases. Let's imagine the following case with a super convoluted setup with three themes/plugins and the site itself all trying to define the same component. Internally, Docusaurus loads these themes as a "stack".
|
||||
|
||||
```text
|
||||
+-------------------------------------------------+
|
||||
| `website/src/theme/CodeBlock.js` | <-- `@theme/CodeBlock` always points to the top
|
||||
+-------------------------------------------------+
|
||||
| `theme-live-codeblock/theme/CodeBlock/index.js` | <-- `@theme-original/CodeBlock` points to the topmost non-swizzled component
|
||||
+-------------------------------------------------+
|
||||
| `plugin-awesome-codeblock/theme/CodeBlock.js` |
|
||||
+-------------------------------------------------+
|
||||
| `theme-classic/theme/CodeBlock/index.js` | <-- `@theme-init/CodeBlock` always points to the bottom
|
||||
+-------------------------------------------------+
|
||||
```
|
||||
|
||||
The components in this "stack" are pushed in the order of `preset plugins > preset themes > plugins > themes > site`, so the swizzled component in `website/src/theme` always comes out on top because it's loaded last.
|
||||
|
||||
`@theme/*` always points to the topmost component—when `CodeBlock` is swizzled, all other components requesting `@theme/CodeBlock` receive the swizzled version.
|
||||
|
||||
`@theme-original/*` always points to the topmost non-swizzled component. That's why you can import `@theme-original/CodeBlock` in the swizzled component—it points to the next one in the "component stack", a theme-provided one. Plugin authors should not try to use this because your component could be the topmost component and cause a self-import.
|
||||
|
||||
`@theme-init/*` always points to the bottommost component—usually, this comes from the theme or plugin that first provides this component. Individual plugins / themes trying to enhance code block can safely use `@theme-init/CodeBlock` to get its basic version. Site creators should generally not use this because you likely want to enhance the _topmost_ instead of the _bottommost_ component. It's also possible that the `@theme-init/CodeBlock` alias does not exist at all—Docusaurus only creates it when it points to a different one from `@theme-original/CodeBlock`, i.e. when it's provided by more than one theme. We don't waste aliases!
|
||||
|
||||
## Client modules {#client-modules}
|
||||
|
||||
Client modules are part of your site's bundle, just like theme components. However, they are usually side-effect-ful. Client modules are anything that can be `import`ed by Webpack—CSS, JS, etc. JS scripts usually work on the global context, like registering event listeners, creating global variables...
|
||||
|
||||
These modules are imported globally before React even renders the initial UI.
|
||||
|
||||
```js title="@docusaurus/core/App.tsx"
|
||||
// How it works under the hood
|
||||
import '@generated/client-modules';
|
||||
```
|
||||
|
||||
Plugins and sites can both declare client modules, through [`getClientModules`](../api/plugin-methods/lifecycle-apis.mdx#getClientModules) and [`siteConfig.clientModules`](../api/docusaurus.config.js.mdx#clientModules), respectively.
|
||||
|
||||
Client modules are called during server-side rendering as well, so remember to check the [execution environment](./ssg.mdx#escape-hatches) before accessing client-side globals.
|
||||
|
||||
```js title="mySiteGlobalJs.js"
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
// As soon as the site loads in the browser, register a global event listener
|
||||
window.addEventListener('keydown', (e) => {
|
||||
if (e.code === 'Period') {
|
||||
location.assign(location.href.replace('.com', '.dev'));
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
CSS stylesheets imported as client modules are [global](../styling-layout.mdx#global-styles).
|
||||
|
||||
```css title="mySiteGlobalCss.css"
|
||||
/* This stylesheet is global. */
|
||||
.globalSelector {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
### Client module lifecycles {#client-module-lifecycles}
|
||||
|
||||
Besides introducing side-effects, client modules can optionally export two lifecycle functions: `onRouteUpdate` and `onRouteDidUpdate`.
|
||||
|
||||
Because Docusaurus builds a single-page application, `script` tags will only be executed the first time the page loads, but will not re-execute on page transitions. These lifecycles are useful if you have some imperative JS logic that should execute every time a new page has loaded, e.g., to manipulate DOM elements, to send analytics data, etc.
|
||||
|
||||
For every route transition, there will be several important timings:
|
||||
|
||||
1. The user clicks a link, which causes the router to change its current location.
|
||||
2. Docusaurus preloads the next route's assets, while keeping displaying the current page's content.
|
||||
3. The next route's assets have loaded.
|
||||
4. The new location's route component gets rendered to DOM.
|
||||
|
||||
`onRouteUpdate` will be called at event (2), and `onRouteDidUpdate` will be called at (4). They both receive the current location and the previous location (which can be `null`, if this is the first screen).
|
||||
|
||||
`onRouteUpdate` can optionally return a "cleanup" callback, which will be called at (3). For example, if you want to display a progress bar, you can start a timeout in `onRouteUpdate`, and clear the timeout in the callback. (The classic theme already provides an `nprogress` integration this way.)
|
||||
|
||||
Note that the new page's DOM is only available during event (4). If you need to manipulate the new page's DOM, you'll likely want to use `onRouteDidUpdate`, which will be fired as soon as the DOM on the new page has mounted.
|
||||
|
||||
```js title="myClientModule.js"
|
||||
export function onRouteDidUpdate({location, previousLocation}) {
|
||||
// Don't execute if we are still on the same page; the lifecycle may be fired
|
||||
// because the hash changes (e.g. when navigating between headings)
|
||||
if (location.pathname !== previousLocation?.pathname) {
|
||||
const title = document.getElementsByTagName('h1')[0];
|
||||
if (title) {
|
||||
title.innerText += '❤️';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function onRouteUpdate({location, previousLocation}) {
|
||||
if (location.pathname !== previousLocation?.pathname) {
|
||||
const progressBarTimeout = window.setTimeout(() => {
|
||||
nprogress.start();
|
||||
}, delay);
|
||||
return () => window.clearTimeout(progressBarTimeout);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
```
|
||||
|
||||
Or, if you are using TypeScript and you want to leverage contextual typing:
|
||||
|
||||
```ts title="myClientModule.ts"
|
||||
import type {ClientModule} from '@docusaurus/types';
|
||||
|
||||
const module: ClientModule = {
|
||||
onRouteUpdate({location, previousLocation}) {
|
||||
// ...
|
||||
},
|
||||
onRouteDidUpdate({location, previousLocation}) {
|
||||
// ...
|
||||
},
|
||||
};
|
||||
export default module;
|
||||
```
|
||||
|
||||
Both lifecycles will fire on first render, but they will not fire on server-side, so you can safely access browser globals in them.
|
||||
|
||||
:::tip Prefer using React
|
||||
|
||||
Client module lifecycles are purely imperative, and you can't use React hooks or access React contexts within them. If your operations are state-driven or involve complicated DOM manipulations, you should consider [swizzling components](../swizzling.mdx) instead.
|
||||
|
||||
:::
|
11
website/versioned_docs/version-3.3.2/advanced/index.mdx
Normal file
11
website/versioned_docs/version-3.3.2/advanced/index.mdx
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Advanced Tutorials
|
||||
|
||||
This section is not going to be very structured, but we will cover the following topics:
|
||||
|
||||
```mdx-code-block
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
<DocCardList />
|
||||
```
|
||||
|
||||
We will assume that you have finished the guides, and know the basics like how to configure plugins, how to write React components, etc. These sections will have plugin authors and code contributors in mind, so we may occasionally refer to [plugin APIs](../api/plugin-methods/README.mdx) or other architecture details. Don't panic if you don't understand everything😉
|
129
website/versioned_docs/version-3.3.2/advanced/plugins.mdx
Normal file
129
website/versioned_docs/version-3.3.2/advanced/plugins.mdx
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Plugins
|
||||
|
||||
Plugins are the building blocks of features in a Docusaurus site. Each plugin handles its own individual feature. Plugins may work and be distributed as part of a bundle via presets.
|
||||
|
||||
## Creating plugins {#creating-plugins}
|
||||
|
||||
A plugin is a function that takes two parameters: `context` and `options`. It returns a plugin instance object (or a promise). You can create plugins as functions or modules. For more information, refer to the [plugin method references section](../api/plugin-methods/README.mdx).
|
||||
|
||||
### Function definition {#function-definition}
|
||||
|
||||
You can use a plugin as a function directly included in the Docusaurus config file:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// ...
|
||||
plugins: [
|
||||
// highlight-start
|
||||
async function myPlugin(context, options) {
|
||||
// ...
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
async loadContent() {
|
||||
// ...
|
||||
},
|
||||
async contentLoaded({content, actions}) {
|
||||
// ...
|
||||
},
|
||||
/* other lifecycle API */
|
||||
};
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Module definition {#module-definition}
|
||||
|
||||
You can use a plugin as a module path referencing a separate file or npm package:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// ...
|
||||
plugins: [
|
||||
// without options:
|
||||
'./my-plugin',
|
||||
// or with options:
|
||||
['./my-plugin', options],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Then in the folder `my-plugin`, you can create an `index.js` such as this:
|
||||
|
||||
```js title="my-plugin/index.js"
|
||||
export default async function myPlugin(context, options) {
|
||||
// ...
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
async loadContent() {
|
||||
/* ... */
|
||||
},
|
||||
async contentLoaded({content, actions}) {
|
||||
/* ... */
|
||||
},
|
||||
/* other lifecycle API */
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
You can view all plugins installed in your site using the [debug plugin's metadata panel](/__docusaurus/debug/metadata).
|
||||
|
||||
Plugins come as several types:
|
||||
|
||||
- `package`: an external package you installed
|
||||
- `project`: a plugin you created in your project, given to Docusaurus as a local file path
|
||||
- `local`: a plugin created using the function definition
|
||||
- `synthetic`: a "fake plugin" Docusaurus created internally, so we take advantage of our modular architecture and don't let the core do much special work. You won't see this in the metadata because it's an implementation detail.
|
||||
|
||||
You can access them on the client side with `useDocusaurusContext().siteMetadata.pluginVersions`.
|
||||
|
||||
## Plugin design {#plugin-design}
|
||||
|
||||
Docusaurus' implementation of the plugins system provides us with a convenient way to hook into the website's lifecycle to modify what goes on during development/build, which involves (but is not limited to) extending the webpack config, modifying the data loaded, and creating new components to be used in a page.
|
||||
|
||||
### Theme design {#theme-design}
|
||||
|
||||
When plugins have loaded their content, the data is made available to the client side through actions like [`createData` + `addRoute`](../api/plugin-methods/lifecycle-apis.mdx#addRoute) or [`setGlobalData`](../api/plugin-methods/lifecycle-apis.mdx#setGlobalData). This data has to be _serialized_ to plain strings, because [plugins and themes run in different environments](./architecture.mdx). Once the data arrives on the client side, the rest becomes familiar to React developers: data is passed along components, components are bundled with Webpack, and rendered to the window through `ReactDOM.render`...
|
||||
|
||||
**Themes provide the set of UI components to render the content.** Most content plugins need to be paired with a theme in order to be actually useful. The UI is a separate layer from the data schema, which makes swapping designs easy.
|
||||
|
||||
For example, a Docusaurus blog may consist of a blog plugin and a blog theme.
|
||||
|
||||
:::note
|
||||
|
||||
This is a contrived example: in practice, `@docusaurus/theme-classic` provides the theme for docs, blog, and layouts.
|
||||
|
||||
:::
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// highlight-next-line
|
||||
themes: ['theme-blog'],
|
||||
plugins: ['plugin-content-blog'],
|
||||
};
|
||||
```
|
||||
|
||||
And if you want to use Bootstrap styling, you can swap out the theme with `theme-blog-bootstrap` (another fictitious non-existing theme):
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// highlight-next-line
|
||||
themes: ['theme-blog-bootstrap'],
|
||||
plugins: ['plugin-content-blog'],
|
||||
};
|
||||
```
|
||||
|
||||
Now, although the theme receives the same data from the plugin, how the theme chooses to _render_ the data as UI can be drastically different.
|
||||
|
||||
While themes share the exact same lifecycle methods with plugins, themes' implementations can look very different from those of plugins based on themes' designed objectives.
|
||||
|
||||
Themes are designed to complete the build of your Docusaurus site and supply the components used by your site, plugins, and the themes themselves. A theme still acts like a plugin and exposes some lifecycle methods, but most likely they would not use [`loadContent`](../api/plugin-methods/lifecycle-apis.mdx#loadContent), since they only receive data from plugins, but don't generate data themselves; themes are typically also accompanied by an `src/theme` directory full of components, which are made known to the core through the [`getThemePath`](../api/plugin-methods/extend-infrastructure.mdx#getThemePath) lifecycle.
|
||||
|
||||
To summarize:
|
||||
|
||||
- Themes share the same lifecycle methods with Plugins
|
||||
- Themes are run after all existing Plugins
|
||||
- Themes add component aliases by providing `getThemePath`.
|
289
website/versioned_docs/version-3.3.2/advanced/routing.mdx
Normal file
289
website/versioned_docs/version-3.3.2/advanced/routing.mdx
Normal file
|
@ -0,0 +1,289 @@
|
|||
---
|
||||
description: "Docusaurus' routing system follows single-page application conventions: one route, one component."
|
||||
---
|
||||
|
||||
# Routing
|
||||
|
||||
```mdx-code-block
|
||||
import Link from '@docusaurus/Link';
|
||||
import {useLatestVersion, useActiveDocContext} from '@docusaurus/plugin-content-docs/client';
|
||||
import {useLocation} from '@docusaurus/router';
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
```
|
||||
|
||||
Docusaurus' routing system follows single-page application conventions: one route, one component. In this section, we will begin by talking about routing within the three content plugins (docs, blog, and pages), and then go beyond to talk about the underlying routing system.
|
||||
|
||||
## Routing in content plugins {#routing-in-content-plugins}
|
||||
|
||||
Every content plugin provides a `routeBasePath` option. It defines where the plugins append their routes to. By default, the docs plugin puts its routes under `/docs`; the blog plugin, `/blog`; and the pages plugin, `/`. You can think about the route structure like this:
|
||||
|
||||
```mermaid
|
||||
graph LR;
|
||||
A(["https://example.com/"])
|
||||
B(["/base-url/"])
|
||||
C(["/docs/"])
|
||||
D(["/blog/"])
|
||||
E(["/"])
|
||||
F["All docs <br/>routes"]
|
||||
G["All blog <br/>routes"]
|
||||
H["All pages <br/>routes"]
|
||||
A---B;
|
||||
B---C;
|
||||
B---D;
|
||||
B---E;
|
||||
C---F;
|
||||
D---G;
|
||||
E---H;
|
||||
```
|
||||
|
||||
Any route will be matched against this nested route config until a good match is found. For example, when given a route `/docs/configuration`, Docusaurus first enters the `/docs` branch, and then searches among the subroutes created by the docs plugin.
|
||||
|
||||
Changing `routeBasePath` can effectively alter your site's route structure. For example, in [Docs-only mode](../guides/docs/docs-introduction.mdx#docs-only-mode), we mentioned that configuring `routeBasePath: '/'` for docs means that all routes that the docs plugin create would not have the `/docs` prefix, yet it doesn't prevent you from having more subroutes like `/blog` created by other plugins.
|
||||
|
||||
Next, let's look at how the three plugins structure their own "boxes of subroutes".
|
||||
|
||||
### Pages routing {#pages-routing}
|
||||
|
||||
Pages routing are straightforward: the file paths directly map to URLs, without any other way to customize. See the [pages docs](../guides/creating-pages.mdx#routing) for more information.
|
||||
|
||||
The component used for Markdown pages is `@theme/MDXPage`. React pages are directly used as the route's component.
|
||||
|
||||
### Blog routing {#blog-routing}
|
||||
|
||||
The blog creates the following routes:
|
||||
|
||||
- **Posts list pages**: `/`, `/page/2`, `/page/3`...
|
||||
- The route is customizable through the `pageBasePath` option.
|
||||
- The component is `@theme/BlogListPage`.
|
||||
- **Post pages**: `/2021/11/21/algolia-docsearch-migration`, `/2021/05/12/announcing-docusaurus-two-beta`...
|
||||
- Generated from each Markdown post.
|
||||
- The routes are fully customizable through the `slug` front matter.
|
||||
- The component is `@theme/BlogPostPage`.
|
||||
- **Tags list page**: `/tags`
|
||||
- The route is customizable through the `tagsBasePath` option.
|
||||
- The component is `@theme/BlogTagsListPage`.
|
||||
- **Tag pages**: `/tags/adoption`, `/tags/beta`...
|
||||
- Generated through the tags defined in each post's front matter.
|
||||
- The routes always have base defined in `tagsBasePath`, but the subroutes are customizable through the tag's `permalink` field.
|
||||
- The component is `@theme/BlogTagsPostsPage`.
|
||||
- **Archive page**: `/archive`
|
||||
- The route is customizable through the `archiveBasePath` option.
|
||||
- The component is `@theme/BlogArchivePage`.
|
||||
|
||||
### Docs routing {#docs-routing}
|
||||
|
||||
The docs is the only plugin that creates **nested routes**. At the top, it registers [**version paths**](../guides/docs/versioning.mdx): `/`, `/next`, `/2.0.0-beta.13`... which provide the version context, including the layout and sidebar. This ensures that when switching between individual docs, the sidebar's state is preserved, and that you can switch between versions through the navbar dropdown while staying on the same doc. The component used is `@theme/DocPage`.
|
||||
|
||||
```mdx-code-block
|
||||
export const URLPath = () => <code>{useLocation().pathname}</code>;
|
||||
|
||||
export const FilePath = () => {
|
||||
const currentVersion = useActiveDocContext('default').activeVersion.name;
|
||||
return <code>{currentVersion === 'current' ? './docs/' : `./versioned_docs/version-${currentVersion}/`}advanced/routing.md</code>;
|
||||
}
|
||||
```
|
||||
|
||||
The individual docs are rendered in the remaining space after the navbar, footer, sidebar, etc. have all been provided by the `DocPage` component. For example, this page, <URLPath />, is generated from the file at <FilePath />. The component used is `@theme/DocItem`.
|
||||
|
||||
The doc's `slug` front matter customizes the last part of the route, but the base route is always defined by the plugin's `routeBasePath` and the version's `path`.
|
||||
|
||||
### File paths and URL paths {#file-paths-and-url-paths}
|
||||
|
||||
Throughout the documentation, we always try to be unambiguous about whether we are talking about file paths or URL paths. Content plugins usually map file paths directly to URL paths, for example, `./docs/advanced/routing.md` will become `/docs/advanced/routing`. However, with `slug`, you can make URLs totally decoupled from the file structure.
|
||||
|
||||
When writing links in Markdown, you could either mean a _file path_, or a _URL path_, which Docusaurus would use several heuristics to determine.
|
||||
|
||||
- If the path has a `@site` prefix, it is _always_ an asset file path.
|
||||
- If the path has an `http(s)://` prefix, it is _always_ a URL path.
|
||||
- If the path doesn't have an extension, it is a URL path. For example, a link `[page](../plugins)` on a page with URL `/docs/advanced/routing` will link to `/docs/plugins`. Docusaurus will only detect broken links when building your site (when it knows the full route structure), but will make no assumptions about the existence of a file. It is exactly equivalent to writing `<a href="../plugins">page</a>` in a JSX file.
|
||||
- If the path has an `.md(x)` extension, Docusaurus would try to resolve that Markdown file to a URL, and replace the file path with a URL path.
|
||||
- If the path has any other extension, Docusaurus would treat it as [an asset](../guides/markdown-features/markdown-features-assets.mdx) and bundle it.
|
||||
|
||||
The following directory structure may help you visualize this file → URL mapping. Assume that there's no slug customization in any page.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>A sample site structure</summary>
|
||||
|
||||
```bash
|
||||
.
|
||||
├── blog # blog plugin has routeBasePath: '/blog'
|
||||
│ ├── 2019-05-28-first-blog-post.md # -> /blog/2019/05/28/first-blog-post
|
||||
│ ├── 2019-05-29-long-blog-post.md # -> /blog/2019/05/29/long-blog-post
|
||||
│ ├── 2021-08-01-mdx-blog-post.mdx # -> /blog/2021/08/01/mdx-blog-post
|
||||
│ └── 2021-08-26-welcome
|
||||
│ ├── docusaurus-plushie-banner.jpeg
|
||||
│ └── index.md # -> /blog/2021/08/26/welcome
|
||||
├── docs # docs plugin has routeBasePath: '/docs'; current version has base path '/'
|
||||
│ ├── intro.md # -> /docs/intro
|
||||
│ ├── tutorial-basics
|
||||
│ │ ├── _category_.json
|
||||
│ │ ├── congratulations.md # -> /docs/tutorial-basics/congratulations
|
||||
│ │ └── markdown-features.mdx # -> /docs/tutorial-basics/markdown-features
|
||||
│ └── tutorial-extras
|
||||
│ ├── _category_.json
|
||||
│ ├── manage-docs-versions.md # -> /docs/tutorial-extras/manage-docs-versions
|
||||
│ └── translate-your-site.md # -> /docs/tutorial-extras/translate-your-site
|
||||
├── src
|
||||
│ └── pages # pages plugin has routeBasePath: '/'
|
||||
│ ├── index.module.css
|
||||
│ ├── index.tsx # -> /
|
||||
│ └── markdown-page.md # -> /markdown-page
|
||||
└── versioned_docs
|
||||
└── version-1.0.0 # version has base path '/1.0.0'
|
||||
├── intro.md # -> /docs/1.0.0/intro
|
||||
├── tutorial-basics
|
||||
│ ├── _category_.json
|
||||
│ ├── congratulations.md # -> /docs/1.0.0/tutorial-basics/congratulations
|
||||
│ └── markdown-features.mdx # -> /docs/1.0.0/tutorial-basics/markdown-features
|
||||
└── tutorial-extras
|
||||
├── _category_.json
|
||||
├── manage-docs-versions.md # -> /docs/1.0.0/tutorial-extras/manage-docs-versions
|
||||
└── translate-your-site.md # -> /docs/1.0.0/tutorial-extras/translate-your-site
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
So much about content plugins. Let's take one step back and talk about how routing works in a Docusaurus app in general.
|
||||
|
||||
## Routes become HTML files {#routes-become-html-files}
|
||||
|
||||
Because Docusaurus is a server-side rendering framework, all routes generated will be server-side rendered into static HTML files. If you are familiar with the behavior of HTTP servers like [Apache2](https://httpd.apache.org/docs/trunk/getting-started.html), you will understand how this is done: when the browser sends a request to the route `/docs/advanced/routing`, the server interprets that as request for the HTML file `/docs/advanced/routing/index.html`, and returns that.
|
||||
|
||||
The `/docs/advanced/routing` route can correspond to either `/docs/advanced/routing/index.html` or `/docs/advanced/routing.html`. Some hosting providers differentiate between them using the presence of a trailing slash, and may or may not tolerate the other. Read more in the [trailing slash guide](https://github.com/slorber/trailing-slash-guide).
|
||||
|
||||
For example, the build output of the directory above is (ignoring other assets and JS bundle):
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Output of the above workspace</summary>
|
||||
|
||||
```bash
|
||||
build
|
||||
├── 404.html # /404/
|
||||
├── blog
|
||||
│ ├── archive
|
||||
│ │ └── index.html # /blog/archive/
|
||||
│ ├── first-blog-post
|
||||
│ │ └── index.html # /blog/first-blog-post/
|
||||
│ ├── index.html # /blog/
|
||||
│ ├── long-blog-post
|
||||
│ │ └── index.html # /blog/long-blog-post/
|
||||
│ ├── mdx-blog-post
|
||||
│ │ └── index.html # /blog/mdx-blog-post/
|
||||
│ ├── tags
|
||||
│ │ ├── docusaurus
|
||||
│ │ │ └── index.html # /blog/tags/docusaurus/
|
||||
│ │ ├── hola
|
||||
│ │ │ └── index.html # /blog/tags/hola/
|
||||
│ │ └── index.html # /blog/tags/
|
||||
│ └── welcome
|
||||
│ └── index.html # /blog/welcome/
|
||||
├── docs
|
||||
│ ├── 1.0.0
|
||||
│ │ ├── intro
|
||||
│ │ │ └── index.html # /docs/1.0.0/intro/
|
||||
│ │ ├── tutorial-basics
|
||||
│ │ │ ├── congratulations
|
||||
│ │ │ │ └── index.html # /docs/1.0.0/tutorial-basics/congratulations/
|
||||
│ │ │ └── markdown-features
|
||||
│ │ │ └── index.html # /docs/1.0.0/tutorial-basics/markdown-features/
|
||||
│ │ └── tutorial-extras
|
||||
│ │ ├── manage-docs-versions
|
||||
│ │ │ └── index.html # /docs/1.0.0/tutorial-extras/manage-docs-versions/
|
||||
│ │ └── translate-your-site
|
||||
│ │ └── index.html # /docs/1.0.0/tutorial-extras/translate-your-site/
|
||||
│ ├── intro
|
||||
│ │ └── index.html # /docs/1.0.0/intro/
|
||||
│ ├── tutorial-basics
|
||||
│ │ ├── congratulations
|
||||
│ │ │ └── index.html # /docs/tutorial-basics/congratulations/
|
||||
│ │ └── markdown-features
|
||||
│ │ └── index.html # /docs/tutorial-basics/markdown-features/
|
||||
│ └── tutorial-extras
|
||||
│ ├── manage-docs-versions
|
||||
│ │ └── index.html # /docs/tutorial-extras/manage-docs-versions/
|
||||
│ └── translate-your-site
|
||||
│ └── index.html # /docs/tutorial-extras/translate-your-site/
|
||||
├── index.html # /
|
||||
└── markdown-page
|
||||
└── index.html # /markdown-page/
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
If `trailingSlash` is set to `false`, the build would emit `intro.html` instead of `intro/index.html`.
|
||||
|
||||
All HTML files will reference its JS assets using absolute URLs, so in order for the correct assets to be located, you have to configure the `baseUrl` field. Note that `baseUrl` doesn't affect the emitted bundle's file structure: the base URL is one level above the Docusaurus routing system. You can see the aggregate of `url` and `baseUrl` as the actual location of your Docusaurus site.
|
||||
|
||||
For example, the emitted HTML would contain links like `<link rel="preload" href="/assets/js/runtime~main.7ed5108a.js" as="script">`. Because absolute URLs are resolved from the host, if the bundle placed under the path `https://example.com/base/`, the link will point to `https://example.com/assets/js/runtime~main.7ed5108a.js`, which is, well, non-existent. By specifying `/base/` as base URL, the link will correctly point to `/base/assets/js/runtime~main.7ed5108a.js`.
|
||||
|
||||
Localized sites have the locale as part of the base URL as well. For example, `https://docusaurus.io/zh-CN/docs/advanced/routing/` has base URL `/zh-CN/`.
|
||||
|
||||
## Generating and accessing routes {#generating-and-accessing-routes}
|
||||
|
||||
The `addRoute` lifecycle action is used to generate routes. It registers a piece of route config to the route tree, giving a route, a component, and props that the component needs. The props and the component are both provided as paths for the bundler to `require`, because as explained in the [architecture overview](architecture.mdx), server and client only communicate through temp files.
|
||||
|
||||
All routes are aggregated in `.docusaurus/routes.js`, which you can view with the debug plugin's [routes panel](/__docusaurus/debug/routes).
|
||||
|
||||
On the client side, we offer `@docusaurus/router` to access the page's route. `@docusaurus/router` is a re-export of the [`react-router-dom`](https://www.npmjs.com/package/react-router-dom/v/5.3.0) package. For example, you can use `useLocation` to get the current page's [location](https://developer.mozilla.org/en-US/docs/Web/API/Location), and `useHistory` to access the [history object](https://developer.mozilla.org/en-US/docs/Web/API/History). (They are not the same as the browser API, although similar in functionality. Refer to the React Router documentation for specific APIs.)
|
||||
|
||||
This API is **SSR safe**, as opposed to the browser-only `window.location`.
|
||||
|
||||
```jsx title="myComponent.js"
|
||||
import React from 'react';
|
||||
import {useLocation} from '@docusaurus/router';
|
||||
|
||||
export function PageRoute() {
|
||||
// React router provides the current component's route, even in SSR
|
||||
const location = useLocation();
|
||||
return (
|
||||
<span>
|
||||
We are currently on <code>{location.pathname}</code>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
export function PageRoute() {
|
||||
const location = useLocation();
|
||||
return (
|
||||
<span>
|
||||
We are currently on <code>{location.pathname}</code>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
<BrowserWindow>
|
||||
|
||||
<PageRoute />
|
||||
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
## Escaping from SPA redirects {#escaping-from-spa-redirects}
|
||||
|
||||
Docusaurus builds a [single-page application](https://developer.mozilla.org/en-US/docs/Glossary/SPA), where route transitions are done through the `history.push()` method of React router. This operation is done on the client side. However, the prerequisite for a route transition to happen this way is that the target URL is known to our router. Otherwise, the router catches this path and displays a 404 page instead.
|
||||
|
||||
If you put some HTML pages under the `static` folder, they will be copied to the build output and therefore become accessible as part of your website, yet it's not part of the Docusaurus route system. We provide a `pathname://` protocol that allows you to redirect to another part of your domain in a non-SPA fashion, as if this route is an external link.
|
||||
|
||||
```md
|
||||
- [pathname:///pure-html](pathname:///pure-html)
|
||||
```
|
||||
|
||||
<BrowserWindow>
|
||||
|
||||
- [`pathname:///pure-html`](pathname:///pure-html)
|
||||
|
||||
</BrowserWindow>
|
||||
|
||||
The `pathname://` protocol is useful for referencing any content in the static folder. For example, Docusaurus would convert [all Markdown static assets to require() calls](../guides/markdown-features/markdown-features-assets.mdx#static-assets). You can use `pathname://` to keep it a regular link instead of being hashed by Webpack.
|
||||
|
||||
```md title="my-doc.md"
|
||||

|
||||
|
||||
[An asset from the static](pathname:///files/asset.pdf)
|
||||
```
|
||||
|
||||
Docusaurus will only strip the `pathname://` prefix without processing the content.
|
218
website/versioned_docs/version-3.3.2/advanced/ssg.mdx
Normal file
218
website/versioned_docs/version-3.3.2/advanced/ssg.mdx
Normal file
|
@ -0,0 +1,218 @@
|
|||
---
|
||||
sidebar_label: Static site generation
|
||||
description: Docusaurus statically renders your React code into HTML, allowing faster load speed and better SEO.
|
||||
---
|
||||
|
||||
# Static site generation (SSG)
|
||||
|
||||
In [architecture](architecture.mdx), we mentioned that the theme is run in Webpack. But beware: that doesn't mean it always has access to browser globals! The theme is built twice:
|
||||
|
||||
- During **server-side rendering**, the theme is compiled in a sandbox called [React DOM Server](https://reactjs.org/docs/react-dom-server.html). You can see this as a "headless browser", where there is no `window` or `document`, only React. SSR produces static HTML pages.
|
||||
- During **client-side rendering**, the theme is compiled to JavaScript that gets eventually executed in the browser, so it has access to browser variables.
|
||||
|
||||
:::info SSR or SSG?
|
||||
|
||||
_Server-side rendering_ and _static site generation_ can be different concepts, but we use them interchangeably.
|
||||
|
||||
Strictly speaking, Docusaurus is a static site generator, because there's no server-side runtime—we statically render to HTML files that are deployed on a CDN, instead of dynamically pre-rendering on each request. This differs from the working model of [Next.js](https://nextjs.org/).
|
||||
|
||||
:::
|
||||
|
||||
Therefore, while you probably know not to access Node globals like `process` ([or can we?](#node-env)) or the `'fs'` module, you can't freely access browser globals either.
|
||||
|
||||
```jsx
|
||||
import React from 'react';
|
||||
|
||||
export default function WhereAmI() {
|
||||
return <span>{window.location.href}</span>;
|
||||
}
|
||||
```
|
||||
|
||||
This looks like idiomatic React, but if you run `docusaurus build`, you will get an error:
|
||||
|
||||
```
|
||||
ReferenceError: window is not defined
|
||||
```
|
||||
|
||||
This is because during server-side rendering, the Docusaurus app isn't actually run in browser, and it doesn't know what `window` is.
|
||||
|
||||
```mdx-code-block
|
||||
<details id="node-env">
|
||||
<summary>What about <code>process.env.NODE_ENV</code>?</summary>
|
||||
```
|
||||
|
||||
One exception to the "no Node globals" rule is `process.env.NODE_ENV`. In fact, you can use it in React, because Webpack injects this variable as a global:
|
||||
|
||||
```jsx
|
||||
import React from 'react';
|
||||
|
||||
export default function expensiveComp() {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
return <>This component is not shown in development</>;
|
||||
}
|
||||
const res = someExpensiveOperationThatLastsALongTime();
|
||||
return <>{res}</>;
|
||||
}
|
||||
```
|
||||
|
||||
During Webpack build, the `process.env.NODE_ENV` will be replaced with the value, either `'development'` or `'production'`. You will then get different build results after dead code elimination:
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
```mdx-code-block
|
||||
<Tabs>
|
||||
<TabItem value="Development">
|
||||
```
|
||||
|
||||
```diff
|
||||
import React from 'react';
|
||||
|
||||
export default function expensiveComp() {
|
||||
// highlight-next-line
|
||||
if ('development' === 'development') {
|
||||
+ return <>This component is not shown in development</>;
|
||||
}
|
||||
- const res = someExpensiveOperationThatLastsALongTime();
|
||||
- return <>{res}</>;
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
<TabItem value="Production">
|
||||
```
|
||||
|
||||
```diff
|
||||
import React from 'react';
|
||||
|
||||
export default function expensiveComp() {
|
||||
// highlight-next-line
|
||||
- if ('production' === 'development') {
|
||||
- return <>This component is not shown in development</>;
|
||||
- }
|
||||
+ const res = someExpensiveOperationThatLastsALongTime();
|
||||
+ return <>{res}</>;
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
</details>
|
||||
```
|
||||
|
||||
## Understanding SSR {#understanding-ssr}
|
||||
|
||||
React is not just a dynamic UI runtime—it's also a templating engine. Because Docusaurus sites mostly contain static contents, it should be able to work without any JavaScript (which React runs in), but only plain HTML/CSS. And that's what server-side rendering offers: statically rendering your React code into HTML, without any dynamic content. An HTML file has no concept of client state (it's purely markup), hence it shouldn't rely on browser APIs.
|
||||
|
||||
These HTML files are the first to arrive at the user's browser screen when a URL is visited (see [routing](routing.mdx)). Afterwards, the browser fetches and runs other JS code to provide the "dynamic" parts of your site—anything implemented with JavaScript. However, before that, the main content of your page is already visible, allowing faster loading.
|
||||
|
||||
In CSR-only apps, all DOM elements are generated on client side with React, and the HTML file only ever contains one root element for React to mount DOM to; in SSR, React is already facing a fully built HTML page, and it only needs to correlate the DOM elements with the virtual DOM in its model. This step is called "hydration". After React has hydrated the static markup, the app starts to work as any normal React app.
|
||||
|
||||
Note that Docusaurus is ultimately a single-page application, so static site generation is only an optimization (_progressive enhancement_, as it's called), but our functionality does not fully depend on those HTML files. This is contrary to site generators like [Jekyll](https://jekyllrb.com/) and [Docusaurus v1](https://v1.docusaurus.io/), where all files are statically transformed to markup, and interactiveness is added through external JavaScript linked with `<script>` tags. If you inspect the build output, you will still see JS assets under `build/assets/js`, which are, really, the core of Docusaurus.
|
||||
|
||||
## Escape hatches {#escape-hatches}
|
||||
|
||||
If you want to render any dynamic content on your screen that relies on the browser API to be functional at all, for example:
|
||||
|
||||
- Our [live codeblock](../guides/markdown-features/markdown-features-code-blocks.mdx#interactive-code-editor), which runs in the browser's JS runtime
|
||||
- Our [themed image](../guides/markdown-features/markdown-features-assets.mdx#themed-images) that detects the user's color scheme to display different images
|
||||
- The JSON viewer of our debug panel which uses the `window` global for styling
|
||||
|
||||
You may need to escape from SSR since static HTML can't display anything useful without knowing the client state.
|
||||
|
||||
:::warning
|
||||
|
||||
It is important for the first client-side render to produce the exact same DOM structure as server-side rendering, otherwise, React will correlate virtual DOM with the wrong DOM elements.
|
||||
|
||||
Therefore, the naïve attempt of `if (typeof window !== 'undefined) {/* render something */}` won't work appropriately as a browser vs. server detection, because the first client render would instantly render different markup from the server-generated one.
|
||||
|
||||
You can read more about this pitfall in [The Perils of Rehydration](https://www.joshwcomeau.com/react/the-perils-of-rehydration/).
|
||||
|
||||
:::
|
||||
|
||||
We provide several more reliable ways to escape SSR.
|
||||
|
||||
### `<BrowserOnly>` {#browseronly}
|
||||
|
||||
If you need to render some component in browser only (for example, because the component relies on browser specifics to be functional at all), one common approach is to wrap your component with [`<BrowserOnly>`](../docusaurus-core.mdx#browseronly) to make sure it's invisible during SSR and only rendered in CSR.
|
||||
|
||||
```jsx
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
function MyComponent(props) {
|
||||
return (
|
||||
// highlight-start
|
||||
<BrowserOnly fallback={<div>Loading...</div>}>
|
||||
{() => {
|
||||
const LibComponent =
|
||||
require('some-lib-that-accesses-window').LibComponent;
|
||||
return <LibComponent {...props} />;
|
||||
}}
|
||||
</BrowserOnly>
|
||||
// highlight-end
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
It's important to realize that the children of `<BrowserOnly>` is not a JSX element, but a function that _returns_ an element. This is a design decision. Consider this code:
|
||||
|
||||
```jsx
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
|
||||
function MyComponent() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{/* highlight-start */}
|
||||
{/* DON'T DO THIS - doesn't actually work */}
|
||||
<span>page url = {window.location.href}</span>
|
||||
{/* highlight-end */}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
While you may expect that `BrowserOnly` hides away the children during server-side rendering, it actually can't. When the React renderer tries to render this JSX tree, it does see the `{window.location.href}` variable as a node of this tree and tries to render it, although it's actually not used! Using a function ensures that we only let the renderer see the browser-only component when it's needed.
|
||||
|
||||
### `useIsBrowser` {#useisbrowser}
|
||||
|
||||
You can also use the `useIsBrowser()` hook to test if the component is currently in a browser environment. It returns `false` in SSR and `true` is CSR, after first client render. Use this hook if you only need to perform certain conditional operations on client-side, but not render an entirely different UI.
|
||||
|
||||
```jsx
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
|
||||
function MyComponent() {
|
||||
const isBrowser = useIsBrowser();
|
||||
const location = isBrowser ? window.location.href : 'fetching location...';
|
||||
return <span>{location}</span>;
|
||||
}
|
||||
```
|
||||
|
||||
### `useEffect` {#useeffect}
|
||||
|
||||
Lastly, you can put your logic in `useEffect()` to delay its execution until after first CSR. This is most appropriate if you are only performing side-effects but don't _get_ data from the client state.
|
||||
|
||||
```jsx
|
||||
function MyComponent() {
|
||||
useEffect(() => {
|
||||
// Only logged in the browser console; nothing is logged during server-side rendering
|
||||
console.log("I'm now in the browser");
|
||||
}, []);
|
||||
return <span>Some content...</span>;
|
||||
}
|
||||
```
|
||||
|
||||
### `ExecutionEnvironment` {#executionenvironment}
|
||||
|
||||
The [`ExecutionEnvironment`](../docusaurus-core.mdx#executionenvironment) namespace contains several values, and `canUseDOM` is an effective way to detect browser environment.
|
||||
|
||||
Beware that it essentially checked `typeof window !== 'undefined'` under the hood, so you should not use it for rendering-related logic, but only imperative code, like reacting to user input by sending web requests, or dynamically importing libraries, where DOM isn't updated at all.
|
||||
|
||||
```js title="a-client-module.js"
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
document.title = "I'm loaded!";
|
||||
}
|
||||
```
|
|
@ -0,0 +1,706 @@
|
|||
---
|
||||
sidebar_position: 0
|
||||
description: API reference for Docusaurus configuration file.
|
||||
slug: /api/docusaurus-config
|
||||
---
|
||||
|
||||
# `docusaurus.config.js`
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
:::info
|
||||
|
||||
Refer to the Getting Started [**Configuration**](../configuration.mdx) for examples.
|
||||
|
||||
:::
|
||||
|
||||
## Overview {#overview}
|
||||
|
||||
`docusaurus.config.js` contains configurations for your site and is placed in the root directory of your site.
|
||||
|
||||
:::note
|
||||
|
||||
With a [TypeScript](../typescript-support.mdx) Docusaurus codebase your config file may be called `docusaurus.config.ts`. The syntax is broadly identical to the `js` config file with the addition of types. You can see an example on the [Docusaurus Website](https://github.com/facebook/docusaurus/blob/main/website/docusaurus.config.ts) itself.
|
||||
|
||||
:::
|
||||
|
||||
This file is run in Node.js and should export a site configuration object, or a function that creates it.
|
||||
|
||||
The `docusaurus.config.js` file supports:
|
||||
|
||||
- [**ES Modules**](https://flaviocopes.com/es-modules/)
|
||||
- [**CommonJS**](https://flaviocopes.com/commonjs/)
|
||||
- [**TypeScript**](../typescript-support.mdx#typing-config)
|
||||
|
||||
Examples:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
title: 'Docusaurus',
|
||||
url: 'https://docusaurus.io',
|
||||
// your site config ...
|
||||
};
|
||||
```
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default async function createConfigAsync() {
|
||||
return {
|
||||
title: 'Docusaurus',
|
||||
url: 'https://docusaurus.io',
|
||||
// your site config ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
Refer to [**Syntax to declare `docusaurus.config.js`**](../configuration.mdx#syntax-to-declare-docusaurus-config) for a more exhaustive list of examples and explanations.
|
||||
|
||||
:::
|
||||
|
||||
## Required fields {#required-fields}
|
||||
|
||||
### `title` {#title}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
Title for your website. Will be used in metadata and as browser tab title.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
title: 'Docusaurus',
|
||||
};
|
||||
```
|
||||
|
||||
### `url` {#url}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
URL for your website. This can also be considered the top-level hostname. For example, `https://facebook.github.io` is the URL of https://facebook.github.io/metro/, and `https://docusaurus.io` is the URL for https://docusaurus.io. This field is related to the [`baseUrl`](#baseUrl) field.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
url: 'https://docusaurus.io',
|
||||
};
|
||||
```
|
||||
|
||||
### `baseUrl` {#baseUrl}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
Base URL for your site. Can be considered as the path after the host. For example, `/metro/` is the base URL of https://facebook.github.io/metro/. For URLs that have no path, the baseUrl should be set to `/`. This field is related to the [`url`](#url) field. Always has both leading and trailing slash.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
baseUrl: '/',
|
||||
};
|
||||
```
|
||||
|
||||
## Optional fields {#optional-fields}
|
||||
|
||||
### `favicon` {#favicon}
|
||||
|
||||
- Type: `string | undefined`
|
||||
|
||||
Path to your site favicon; must be a URL that can be used in link's href. For example, if your favicon is in `static/img/favicon.ico`:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
favicon: '/img/favicon.ico',
|
||||
};
|
||||
```
|
||||
|
||||
### `trailingSlash` {#trailingSlash}
|
||||
|
||||
- Type: `boolean | undefined`
|
||||
|
||||
Allow to customize the presence/absence of a trailing slash at the end of URLs/links, and how static HTML files are generated:
|
||||
|
||||
- `undefined` (default): keeps URLs untouched, and emit `/docs/myDoc/index.html` for `/docs/myDoc.md`
|
||||
- `true`: add trailing slashes to URLs/links, and emit `/docs/myDoc/index.html` for `/docs/myDoc.md`
|
||||
- `false`: remove trailing slashes from URLs/links, and emit `/docs/myDoc.html` for `/docs/myDoc.md`
|
||||
|
||||
:::tip
|
||||
|
||||
Each static hosting provider serves static files differently (this behavior may even change over time).
|
||||
|
||||
Refer to the [deployment guide](../deployment.mdx) and [slorber/trailing-slash-guide](https://github.com/slorber/trailing-slash-guide) to choose the appropriate setting.
|
||||
|
||||
:::
|
||||
|
||||
### `i18n` {#i18n}
|
||||
|
||||
- Type: `Object`
|
||||
|
||||
The i18n configuration object to [localize your site](../i18n/i18n-introduction.mdx).
|
||||
|
||||
Example:
|
||||
|
||||
{/* cSpell:ignore فارسی */}
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fa'],
|
||||
path: 'i18n',
|
||||
localeConfigs: {
|
||||
en: {
|
||||
label: 'English',
|
||||
direction: 'ltr',
|
||||
htmlLang: 'en-US',
|
||||
calendar: 'gregory',
|
||||
path: 'en',
|
||||
},
|
||||
fa: {
|
||||
label: 'فارسی',
|
||||
direction: 'rtl',
|
||||
htmlLang: 'fa-IR',
|
||||
calendar: 'persian',
|
||||
path: 'fa',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
- `defaultLocale`: The locale that (1) does not have its name in the base URL (2) gets started with `docusaurus start` without `--locale` option (3) will be used for the `<link hrefLang="x-default">` tag
|
||||
- `locales`: List of locales deployed on your site. Must contain `defaultLocale`.
|
||||
- `path`: Root folder which all locale folders are relative to. Can be absolute or relative to the config file. Defaults to `i18n`.
|
||||
- `localeConfigs`: Individual options for each locale.
|
||||
- `label`: The label displayed for this locale in the locales dropdown.
|
||||
- `direction`: `ltr` (default) or `rtl` (for [right-to-left languages](https://developer.mozilla.org/en-US/docs/Glossary/rtl) like Farsi, Arabic, Hebrew, etc.). Used to select the locale's CSS and HTML meta attribute.
|
||||
- `htmlLang`: BCP 47 language tag to use in `<html lang="...">` (or any other DOM tag name) and in `<link ... hreflang="...">`
|
||||
- `calendar`: the [calendar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar) used to calculate the date era. Note that it doesn't control the actual string displayed: `MM/DD/YYYY` and `DD/MM/YYYY` are both `gregory`. To choose the format (`DD/MM/YYYY` or `MM/DD/YYYY`), set your locale name to `en-GB` or `en-US` (`en` means `en-US`).
|
||||
- `path`: Root folder that all plugin localization folders of this locale are relative to. Will be resolved against `i18n.path`. Defaults to the locale's name. Note: this has no effect on the locale's `baseUrl`—customization of base URL is a work-in-progress.
|
||||
|
||||
### `noIndex` {#noIndex}
|
||||
|
||||
- Type: `boolean`
|
||||
|
||||
This option adds `<meta name="robots" content="noindex, nofollow">` to every page to tell search engines to avoid indexing your site (more information [here](https://moz.com/learn/seo/robots-meta-directives)).
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
noIndex: true, // Defaults to `false`
|
||||
};
|
||||
```
|
||||
|
||||
### `onBrokenLinks` {#onBrokenLinks}
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'throw'`
|
||||
|
||||
The behavior of Docusaurus when it detects any broken link.
|
||||
|
||||
By default, it throws an error, to ensure you never ship any broken link.
|
||||
|
||||
:::note
|
||||
|
||||
The broken links detection is only available for a production build (`docusaurus build`).
|
||||
|
||||
:::
|
||||
|
||||
### `onBrokenAnchors` {#onBrokenAnchors}
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'throw'`
|
||||
|
||||
The behavior of Docusaurus when it detects any broken anchor declared with the `Heading` component of Docusaurus.
|
||||
|
||||
By default, it prints a warning, to let you know about your broken anchors.
|
||||
|
||||
### `onBrokenMarkdownLinks` {#onBrokenMarkdownLinks}
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'throw'`
|
||||
|
||||
The behavior of Docusaurus when it detects any broken Markdown link.
|
||||
|
||||
By default, it prints a warning, to let you know about your broken Markdown link.
|
||||
|
||||
### `onDuplicateRoutes` {#onDuplicateRoutes}
|
||||
|
||||
- Type: `'ignore' | 'log' | 'warn' | 'throw'`
|
||||
|
||||
The behavior of Docusaurus when it detects any [duplicate routes](/guides/creating-pages.mdx#duplicate-routes).
|
||||
|
||||
By default, it displays a warning after you run `yarn start` or `yarn build`.
|
||||
|
||||
### `tagline` {#tagline}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The tagline for your website.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
tagline:
|
||||
'Docusaurus makes it easy to maintain Open Source documentation websites.',
|
||||
};
|
||||
```
|
||||
|
||||
### `organizationName` {#organizationName}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The GitHub user or organization that owns the repository. You don't need this if you are not using the `docusaurus deploy` command.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// Docusaurus' organization is facebook
|
||||
organizationName: 'facebook',
|
||||
};
|
||||
```
|
||||
|
||||
### `projectName` {#projectName}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The name of the GitHub repository. You don't need this if you are not using the `docusaurus deploy` command.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
projectName: 'docusaurus',
|
||||
};
|
||||
```
|
||||
|
||||
### `deploymentBranch` {#deploymentBranch}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The name of the branch to deploy the static files to. You don't need this if you are not using the `docusaurus deploy` command.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
deploymentBranch: 'gh-pages',
|
||||
};
|
||||
```
|
||||
|
||||
### `githubHost` {#githubHost}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The hostname of your server. Useful if you are using GitHub Enterprise. You don't need this if you are not using the `docusaurus deploy` command.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
githubHost: 'github.com',
|
||||
};
|
||||
```
|
||||
|
||||
### `githubPort` {#githubPort}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
The port of your server. Useful if you are using GitHub Enterprise. You don't need this if you are not using the `docusaurus deploy` command.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
githubPort: '22',
|
||||
};
|
||||
```
|
||||
|
||||
### `themeConfig` {#themeConfig}
|
||||
|
||||
- Type: `Object`
|
||||
|
||||
The [theme configuration](./themes/theme-configuration.mdx) object to customize your site UI like navbar and footer.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
themeConfig: {
|
||||
docs: {
|
||||
sidebar: {
|
||||
hideable: false,
|
||||
autoCollapseCategories: false,
|
||||
},
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: 'light',
|
||||
disableSwitch: false,
|
||||
respectPrefersColorScheme: true,
|
||||
},
|
||||
navbar: {
|
||||
title: 'Site Title',
|
||||
logo: {
|
||||
alt: 'Site Logo',
|
||||
src: 'img/logo.svg',
|
||||
width: 32,
|
||||
height: 32,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
to: 'docs/docusaurus.config.js',
|
||||
activeBasePath: 'docs',
|
||||
label: 'docusaurus.config.js',
|
||||
position: 'left',
|
||||
},
|
||||
// ... other links
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Docs',
|
||||
to: 'docs/doc1',
|
||||
},
|
||||
],
|
||||
},
|
||||
// ... other links
|
||||
],
|
||||
logo: {
|
||||
alt: 'Meta Open Source Logo',
|
||||
src: 'img/meta_oss_logo.png',
|
||||
href: 'https://opensource.fb.com',
|
||||
width: 160,
|
||||
height: 51,
|
||||
},
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`, // You can also put own HTML here
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### `plugins` {#plugins}
|
||||
|
||||
- Type: `PluginConfig[]`
|
||||
|
||||
```ts
|
||||
type PluginConfig = string | [string, any] | PluginModule | [PluginModule, any];
|
||||
```
|
||||
|
||||
See [plugin method references](./plugin-methods/README.mdx) for the shape of a `PluginModule`.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
plugins: [
|
||||
'docusaurus-plugin-awesome',
|
||||
['docusuarus-plugin-confetti', {fancy: false}],
|
||||
() => ({
|
||||
postBuild() {
|
||||
console.log('Build finished');
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### `themes` {#themes}
|
||||
|
||||
- Type: `PluginConfig[]`
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
themes: ['@docusaurus/theme-classic'],
|
||||
};
|
||||
```
|
||||
|
||||
### `presets` {#presets}
|
||||
|
||||
- Type: `PresetConfig[]`
|
||||
|
||||
```ts
|
||||
type PresetConfig = string | [string, any];
|
||||
```
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
presets: [],
|
||||
};
|
||||
```
|
||||
|
||||
### `markdown` {#markdown}
|
||||
|
||||
The global Docusaurus Markdown config.
|
||||
|
||||
- Type: `MarkdownConfig`
|
||||
|
||||
```ts
|
||||
type MarkdownPreprocessor = (args: {
|
||||
filePath: string;
|
||||
fileContent: string;
|
||||
}) => string;
|
||||
|
||||
type MDX1CompatOptions =
|
||||
| boolean
|
||||
| {
|
||||
comments: boolean;
|
||||
admonitions: boolean;
|
||||
headingIds: boolean;
|
||||
};
|
||||
|
||||
export type ParseFrontMatter = (params: {
|
||||
filePath: string;
|
||||
fileContent: string;
|
||||
defaultParseFrontMatter: ParseFrontMatter;
|
||||
}) => Promise<{
|
||||
frontMatter: {[key: string]: unknown};
|
||||
content: string;
|
||||
}>;
|
||||
|
||||
type MarkdownAnchorsConfig = {
|
||||
maintainCase: boolean;
|
||||
};
|
||||
|
||||
type MarkdownConfig = {
|
||||
format: 'mdx' | 'md' | 'detect';
|
||||
mermaid: boolean;
|
||||
preprocessor?: MarkdownPreprocessor;
|
||||
parseFrontMatter?: ParseFrontMatter;
|
||||
mdx1Compat: MDX1CompatOptions;
|
||||
remarkRehypeOptions: object; // see https://github.com/remarkjs/remark-rehype#options
|
||||
anchors: MarkdownAnchorsConfig;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
markdown: {
|
||||
format: 'mdx',
|
||||
mermaid: true,
|
||||
preprocessor: ({filePath, fileContent}) => {
|
||||
return fileContent.replaceAll('{{MY_VAR}}', 'MY_VALUE');
|
||||
},
|
||||
parseFrontMatter: async (params) => {
|
||||
const result = await params.defaultParseFrontMatter(params);
|
||||
result.frontMatter.description =
|
||||
result.frontMatter.description?.replaceAll('{{MY_VAR}}', 'MY_VALUE');
|
||||
return result;
|
||||
},
|
||||
mdx1Compat: {
|
||||
comments: true,
|
||||
admonitions: true,
|
||||
headingIds: true,
|
||||
},
|
||||
anchors: {
|
||||
maintainCase: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `format` | `'mdx' \| 'md' \| 'detect'` | `'mdx'` | The default parser format to use for Markdown content. Using 'detect' will select the appropriate format automatically based on file extensions: `.md` vs `.mdx`. |
|
||||
| `mermaid` | `boolean` | `false` | When `true`, allows Docusaurus to render Markdown code blocks with `mermaid` language as Mermaid diagrams. |
|
||||
| `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. |
|
||||
| `parseFrontMatter` | `ParseFrontMatter` | `undefined` | Gives you the ability to provide your own front matter parser, or to enhance the default parser. Read our [front matter guide](../guides/markdown-features/markdown-features-intro.mdx#front-matter) for details. |
|
||||
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. |
|
||||
| `anchors` | `MarkdownAnchorsConfig` | `{maintainCase: false}` | Options to control the behavior of anchors generated from Markdown headings |
|
||||
| `remarkRehypeOptions` | `object` | `undefined` | Makes it possible to pass custom [`remark-rehype` options](https://github.com/remarkjs/remark-rehype#options). |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### `customFields` {#customFields}
|
||||
|
||||
Docusaurus guards `docusaurus.config.js` from unknown fields. To add a custom field, define it on `customFields`.
|
||||
|
||||
- Type: `Object`
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
customFields: {
|
||||
admin: 'endi',
|
||||
superman: 'lol',
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Attempting to add unknown fields in the config will lead to errors during build time:
|
||||
|
||||
```bash
|
||||
Error: The field(s) 'foo', 'bar' are not recognized in docusaurus.config.js
|
||||
```
|
||||
|
||||
### `staticDirectories` {#staticDirectories}
|
||||
|
||||
An array of paths, relative to the site's directory or absolute. Files under these paths will be copied to the build output as-is.
|
||||
|
||||
- Type: `string[]`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
staticDirectories: ['static'],
|
||||
};
|
||||
```
|
||||
|
||||
### `headTags` {#headTags}
|
||||
|
||||
An array of tags that will be inserted in the HTML `<head>`. The values must be objects that contain two properties; `tagName` and `attributes`. `tagName` must be a string that determines the tag being created; eg `"link"`. `attributes` must be an attribute-value map.
|
||||
|
||||
- Type: `{ tagName: string; attributes: Object; }[]`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
headTags: [
|
||||
{
|
||||
tagName: 'link',
|
||||
attributes: {
|
||||
rel: 'icon',
|
||||
href: '/img/docusaurus.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
This would become `<link rel="icon" href="img/docusaurus.png" />` in the generated HTML.
|
||||
|
||||
### `scripts` {#scripts}
|
||||
|
||||
An array of scripts to load. The values can be either strings or plain objects of attribute-value maps. The `<script>` tags will be inserted in the HTML `<head>`. If you use a plain object, the only required attribute is `src`, and any other attributes are permitted (each one should have boolean/string values).
|
||||
|
||||
Note that `<script>` added here are render-blocking, so you might want to add `async: true`/`defer: true` to the objects.
|
||||
|
||||
- Type: `(string | Object)[]`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
scripts: [
|
||||
// String format.
|
||||
'https://docusaurus.io/script.js',
|
||||
// Object format.
|
||||
{
|
||||
src: 'https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js',
|
||||
async: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### `stylesheets` {#stylesheets}
|
||||
|
||||
An array of CSS sources to load. The values can be either strings or plain objects of attribute-value maps. The `<link>` tags will be inserted in the HTML `<head>`. If you use an object, the only required attribute is `href`, and any other attributes are permitted (each one should have boolean/string values).
|
||||
|
||||
- Type: `(string | Object)[]`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
stylesheets: [
|
||||
// String format.
|
||||
'https://docusaurus.io/style.css',
|
||||
// Object format.
|
||||
{
|
||||
href: 'http://mydomain.com/style.css',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
By default, the `<link>` tags will have `rel="stylesheet"`, but you can explicitly add a custom `rel` value to inject any kind of `<link>` tag, not necessarily stylesheets.
|
||||
|
||||
:::
|
||||
|
||||
### `clientModules` {#clientModules}
|
||||
|
||||
An array of [client modules](../advanced/client.mdx#client-modules) to load globally on your site.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
clientModules: ['./mySiteGlobalJs.js', './mySiteGlobalCss.css'],
|
||||
};
|
||||
```
|
||||
|
||||
### `ssrTemplate` {#ssrTemplate}
|
||||
|
||||
An HTML template written in [Eta's syntax](https://eta.js.org/docs/syntax#syntax-overview) that will be used to render your application. This can be used to set custom attributes on the `body` tags, additional `meta` tags, customize the `viewport`, etc. Please note that Docusaurus will rely on the template to be correctly structured in order to function properly, once you do customize it, you will have to make sure that your template is compliant with the requirements from upstream.
|
||||
|
||||
- Type: `string`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
ssrTemplate: `<!DOCTYPE html>
|
||||
<html <%~ it.htmlAttributes %>>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="generator" content="Docusaurus v<%= it.version %>">
|
||||
<% it.metaAttributes.forEach((metaAttribute) => { %>
|
||||
<%~ metaAttribute %>
|
||||
<% }); %>
|
||||
<%~ it.headTags %>
|
||||
<% it.stylesheets.forEach((stylesheet) => { %>
|
||||
<link rel="stylesheet" href="<%= it.baseUrl %><%= stylesheet %>" />
|
||||
<% }); %>
|
||||
<% it.scripts.forEach((script) => { %>
|
||||
<link rel="preload" href="<%= it.baseUrl %><%= script %>" as="script">
|
||||
<% }); %>
|
||||
</head>
|
||||
<body <%~ it.bodyAttributes %>>
|
||||
<%~ it.preBodyTags %>
|
||||
<div id="__docusaurus">
|
||||
<%~ it.appHtml %>
|
||||
</div>
|
||||
<% it.scripts.forEach((script) => { %>
|
||||
<script src="<%= it.baseUrl %><%= script %>"></script>
|
||||
<% }); %>
|
||||
<%~ it.postBodyTags %>
|
||||
</body>
|
||||
</html>`,
|
||||
};
|
||||
```
|
||||
|
||||
### `titleDelimiter` {#titleDelimiter}
|
||||
|
||||
- Type: `string`
|
||||
|
||||
Will be used as title delimiter in the generated `<title>` tag.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
titleDelimiter: '🦖', // Defaults to `|`
|
||||
};
|
||||
```
|
||||
|
||||
### `baseUrlIssueBanner` {#baseUrlIssueBanner}
|
||||
|
||||
- Type: `boolean`
|
||||
|
||||
When enabled, will show a banner in case your site can't load its CSS or JavaScript files, which is a very common issue, often related to a wrong `baseUrl` in site config.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
baseUrlIssueBanner: true, // Defaults to `true`
|
||||
};
|
||||
```
|
||||
|
||||

|
||||
|
||||
:::warning
|
||||
|
||||
This banner needs to inline CSS / JS in case all asset loading fails due to wrong base URL.
|
||||
|
||||
If you have a strict [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), you should rather disable it.
|
||||
|
||||
:::
|
|
@ -0,0 +1,2 @@
|
|||
label: Miscellaneous
|
||||
position: 4
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
sidebar_position: 0
|
||||
slug: /api/misc/create-docusaurus
|
||||
---
|
||||
|
||||
# 📦 create-docusaurus
|
||||
|
||||
A scaffolding utility to help you instantly set up a functional Docusaurus app.
|
||||
|
||||
## Usage {#usage}
|
||||
|
||||
```bash
|
||||
npx create-docusaurus@latest [name] [template] [rootDir]
|
||||
```
|
||||
|
||||
The `name` argument will be used as the site's path as well as the `name` field in the created app's package.json. It can be an absolute path, or a path relative to `rootDir`.
|
||||
|
||||
The `template` argument can be one of the following:
|
||||
|
||||
- `classic`: Uses the classic template (recommended)
|
||||
- `facebook`: Uses the Facebook/Meta template, which contains some Meta-specific setup
|
||||
- A git repo URL (beginning with `https://` or `git@`), which can be cloned to the destination
|
||||
- A local file path relative to CWD, which contains the files to be copied to destination
|
||||
|
||||
The `rootDir` will be used to resolve the absolute path to the site directory. The default is CWD.
|
||||
|
||||
:::warning
|
||||
|
||||
This command should be preferably used in an interactive shell so all features are available.
|
||||
|
||||
:::
|
||||
|
||||
## Options {#options}
|
||||
|
||||
### `-t, --typescript` {#typescript}
|
||||
|
||||
Used when the template argument is a recognized name. Currently, only `classic` provides a TypeScript variant.
|
||||
|
||||
### `-g, --git-strategy` {#git-strategy}
|
||||
|
||||
Used when the template argument is a git repo. It needs to be one of:
|
||||
|
||||
- `deep`: preserves full git history
|
||||
- `shallow`: clones with `--depth=1`
|
||||
- `copy`: does a shallow clone, but does not create a git repo
|
||||
- `custom`: enter your custom git clone command. We will prompt you for it. You can write something like `git clone --depth 10`, and we will append the repository URL and destination directory.
|
||||
|
||||
### `-p, --package-manager` {#package-manager}
|
||||
|
||||
Value should be one of `npm`, `yarn`, `pnpm`, or `bun`. If it's not explicitly provided, Docusaurus will infer one based on:
|
||||
|
||||
- The lockfile already present in the CWD (e.g. if you are setting up website in an existing project)
|
||||
- The command used to invoke `create-docusaurus` (e.g. `npm init`, `npx`, `yarn create`, `bunx`, etc.)
|
||||
- Interactive prompting, in case all heuristics are not present
|
||||
|
||||
### `-s, --skip-install` {#skip-install}
|
||||
|
||||
If provided, Docusaurus will not automatically install dependencies after creating the app. The `--package-manager` option is only useful when you are actually installing dependencies.
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
slug: /api/misc/@docusaurus/eslint-plugin
|
||||
---
|
||||
|
||||
# 📦 eslint-plugin
|
||||
|
||||
[ESLint](https://eslint.org/) is a tool that statically analyzes your code and reports problems or suggests best practices through editor hints and command line. Docusaurus provides an ESLint plugin to enforce best Docusaurus practices.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save-dev @docusaurus/eslint-plugin
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Recommended config
|
||||
|
||||
Add `plugin:@docusaurus/recommended` to the `extends` section of your `.eslintrc` configuration file:
|
||||
|
||||
```json title=".eslintrc"
|
||||
{
|
||||
"extends": ["plugin:@docusaurus/recommended"]
|
||||
}
|
||||
```
|
||||
|
||||
This will enable the `@docusaurus` eslint plugin and use the `recommended` config. See [Supported rules](#supported-rules) below for a list of rules that this will enable.
|
||||
|
||||
### Manual config
|
||||
|
||||
For more fine-grained control, you can also enable the plugin manually and configure the rules you want to use directly:
|
||||
|
||||
```json title=".eslintrc"
|
||||
{
|
||||
"plugins": ["@docusaurus"],
|
||||
"rules": {
|
||||
"@docusaurus/string-literal-i18n-messages": "error",
|
||||
"@docusaurus/no-untranslated-text": "warn"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Supported configs
|
||||
|
||||
- Recommended: recommended rule set for most Docusaurus sites that should be extended from.
|
||||
- All: **all** rules enabled. This will change between minor versions, so you should not use this if you want to avoid unexpected breaking changes.
|
||||
|
||||
## Supported rules
|
||||
|
||||
| Name | Description | |
|
||||
| --- | --- | --- |
|
||||
| [`@docusaurus/no-untranslated-text`](./no-untranslated-text.mdx) | Enforce text labels in JSX to be wrapped by translate calls | |
|
||||
| [`@docusaurus/string-literal-i18n-messages`](./string-literal-i18n-messages.mdx) | Enforce translate APIs to be called on plain text labels | ✅ |
|
||||
| [`@docusaurus/no-html-links`](./no-html-links.mdx) | Ensures @docusaurus/Link is used instead of `<a>` tags | ✅ |
|
||||
| [`@docusaurus/prefer-docusaurus-heading`](./prefer-docusaurus-heading.mdx) | Ensures @theme/Heading is used instead of `<hn>` tags for headings | ✅ |
|
||||
|
||||
✅ = recommended
|
||||
|
||||
## Example configuration
|
||||
|
||||
Here's an example configuration:
|
||||
|
||||
```js title=".eslintrc.js"
|
||||
module.exports = {
|
||||
extends: ['plugin:@docusaurus/recommended'],
|
||||
rules: {
|
||||
'@docusaurus/no-untranslated-text': [
|
||||
'warn',
|
||||
{ignoredStrings: ['·', '—', '×']},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
slug: /api/misc/@docusaurus/eslint-plugin/no-html-links
|
||||
---
|
||||
|
||||
# no-html-links
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
Ensure that the Docusaurus [`<Link>`](../../../docusaurus-core.mdx#link) component is used instead of `<a>` tags.
|
||||
|
||||
The `<Link>` component has prefetching and preloading built-in. It also does build-time broken link detection, and helps Docusaurus understand your site's structure better.
|
||||
|
||||
## Rule Details {#details}
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```html
|
||||
<a href="/page">go to page!</a>
|
||||
|
||||
<a href="https://twitter.com/docusaurus" target="_blank">Twitter</a>
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
import Link from '@docusaurus/Link'
|
||||
|
||||
<Link to="/page">go to page!</Link>
|
||||
|
||||
<Link to="https://twitter.com/docusaurus">Twitter</Link>
|
||||
```
|
||||
|
||||
## Rule Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `ignoreFullyResolved` | `boolean` | `false` | Set to true will not report any `<a>` tags with absolute URLs including a protocol. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
slug: /api/misc/@docusaurus/eslint-plugin/no-untranslated-text
|
||||
---
|
||||
|
||||
# no-untranslated-text
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
Enforce text labels in JSX to be wrapped by translate calls.
|
||||
|
||||
When the [i18n feature](../../../i18n/i18n-introduction.mdx) is used, this rule ensures that all labels appearing on the website are translatable, so no string accidentally slips through untranslated.
|
||||
|
||||
## Rule Details {#details}
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
// Hello World is not translated
|
||||
<Component>Hello World</Component>
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
// Hello World is translated
|
||||
<Component>
|
||||
<Translate>Hello World</Translate>
|
||||
</Component>
|
||||
```
|
||||
|
||||
## Rule Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `ignoredStrings` | `string[]` | `[]` | Text labels that only contain strings in this list will not be reported. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
## When Not To Use It {#when-not-to-use}
|
||||
|
||||
If you're not using the [i18n feature](../../../i18n/i18n-introduction.mdx), you can disable this rule. You can also disable this rule where the text is not supposed to be translated.
|
||||
|
||||
## Further Reading {#further-reading}
|
||||
|
||||
- https://docusaurus.io/docs/docusaurus-core#translate
|
||||
- https://docusaurus.io/docs/docusaurus-core#translate-imperative
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
slug: /api/misc/@docusaurus/eslint-plugin/prefer-docusaurus-heading
|
||||
---
|
||||
|
||||
# prefer-docusaurus-heading
|
||||
|
||||
Ensures that the `@theme/Heading` theme component provided by Docusaurus [`theme-classic`](../../themes/theme-classic.mdx) is used instead of `<hn>` tags for headings.
|
||||
|
||||
## Rule Details {#details}
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```html
|
||||
<h1>This is heading 1</h1>
|
||||
|
||||
<h2>This is heading 2</h2>
|
||||
|
||||
<h3>This is heading 3</h3>
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```javascript
|
||||
import Heading from '@theme/Heading'
|
||||
|
||||
<Heading as='h1'>This is heading 1</Heading>
|
||||
|
||||
<Heading as='h2'>This is heading 2</Heading>
|
||||
|
||||
<Heading as='h3'>This is heading 3</Heading>
|
||||
```
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
slug: /api/misc/@docusaurus/eslint-plugin/string-literal-i18n-messages
|
||||
---
|
||||
|
||||
# string-literal-i18n-messages
|
||||
|
||||
Enforce translate APIs to be called on plain text labels.
|
||||
|
||||
Docusaurus offers the [`docusaurus write-translations`](../../../cli.mdx#docusaurus-write-translations-sitedir) API, which statically extracts the text labels marked as translatable. Dynamic values used in `<Translate>` or `translate()` calls will fail to be extracted. This rule will ensure that all translate calls are statically extractable.
|
||||
|
||||
## Rule Details {#details}
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
const text = 'Some text to be translated'
|
||||
|
||||
// Invalid <Translate> child
|
||||
<Translate>{text}</Translate>
|
||||
|
||||
// Invalid message attribute
|
||||
translate({message: text})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
// Valid <Translate> child
|
||||
<Translate>Some text to be translated</Translate>
|
||||
|
||||
// Valid message attribute
|
||||
translate({message: 'Some text to be translated'})
|
||||
|
||||
// Valid <Translate> child using values object as prop
|
||||
<Translate values={{firstName: 'Sébastien'}}>
|
||||
{'Welcome, {firstName}! How are you?'}
|
||||
</Translate>
|
||||
|
||||
// Valid message attribute using values object as second argument
|
||||
translate({message: 'The logo of site {siteName}'}, {siteName: 'Docusaurus'})
|
||||
```
|
||||
|
||||
## When Not To Use It {#when-not-to-use}
|
||||
|
||||
If you're not using the [i18n feature](../../../i18n/i18n-introduction.mdx), you can disable this rule.
|
||||
|
||||
## Further Reading {#further-reading}
|
||||
|
||||
- https://docusaurus.io/docs/docusaurus-core#translate
|
||||
- https://docusaurus.io/docs/docusaurus-core#translate-imperative
|
BIN
website/versioned_docs/version-3.3.2/api/misc/logger/demo.png
Normal file
BIN
website/versioned_docs/version-3.3.2/api/misc/logger/demo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
slug: /api/misc/@docusaurus/logger
|
||||
---
|
||||
|
||||
# 📦 logger
|
||||
|
||||
An encapsulated logger for semantically formatting console messages.
|
||||
|
||||
Authors of packages in the Docusaurus ecosystem are encouraged to use this package to provide unified log formats.
|
||||
|
||||
## APIs
|
||||
|
||||
It exports a single object as default export: `logger`. `logger` has the following properties:
|
||||
|
||||
- Some useful colors.
|
||||
- `red`
|
||||
- `yellow`
|
||||
- `green`
|
||||
- `bold`
|
||||
- `dim`
|
||||
- Formatters. These functions all have the signature `(msg: unknown) => string`. Note that their implementations are not guaranteed. You should only care about their semantics.
|
||||
- `path`: formats a file path.
|
||||
- `url`: formats a URL.
|
||||
- `name`: formats an identifier.
|
||||
- `code`: formats a code snippet.
|
||||
- `subdue`: subdues the text.
|
||||
- `num`: formats a number.
|
||||
- The `interpolate` function. It is a template literal tag. The syntax can be found below.
|
||||
- Logging functions. All logging functions can both be used as normal functions (similar to the `console.log` family, but only accepts one parameter) or template literal tags.
|
||||
- `info`: prints information.
|
||||
- `warn`: prints a warning that should be paid attention to.
|
||||
- `error`: prints an error (not necessarily halting the program) that signals significant problems.
|
||||
- `success`: prints a success message.
|
||||
- The `report` function. It takes a `ReportingSeverity` value (`ignore`, `log`, `warn`, `throw`) and reports a message according to the severity.
|
||||
|
||||
:::warning A word on the `error` formatter
|
||||
|
||||
Beware that an `error` message, even when it doesn't hang the program, is likely going to cause confusion. When users inspect logs and find an `[ERROR]`, even when the build succeeds, they will assume something is going wrong. Use it sparingly.
|
||||
|
||||
Docusaurus only uses `logger.error` when printing messages immediately before throwing an error, or when user has set the reporting severity of `onBrokenLink`, etc. to `"error"`.
|
||||
|
||||
In addition, `warn` and `error` will color the **entire** message for better attention. If you are printing large blocks of help text about an error, better use `logger.info`.
|
||||
|
||||
:::
|
||||
|
||||
### Using the template literal tag
|
||||
|
||||
The template literal tag evaluates the template and expressions embedded. `interpolate` returns a new string, while other logging functions prints it. Below is a typical usage:
|
||||
|
||||
```js
|
||||
import logger from '@docusaurus/logger';
|
||||
|
||||
logger.info`Hello name=${name}! You have number=${money} dollars. Here are the ${
|
||||
items.length > 1 ? 'items' : 'item'
|
||||
} on the shelf: ${items}
|
||||
To buy anything, enter code=${'buy x'} where code=${'x'} is the item's name; to quit, press code=${'Ctrl + C'}.`;
|
||||
```
|
||||
|
||||
An embedded expression is optionally preceded by a flag in the form `[a-z]+=` (a few lowercase letters, followed by an equals sign, directly preceding the embedded expression). If the expression is not preceded by any flag, it's printed out as-is. Otherwise, it's formatted with one of the formatters:
|
||||
|
||||
- `path=`: `path`
|
||||
- `url=`: `url`
|
||||
- `name=`: `name`
|
||||
- `code=`: `code`
|
||||
- `subdue=`: `subdue`
|
||||
- `number=`: `num`
|
||||
|
||||
If the expression is an array, it's formatted by `` `\n- ${array.join('\n- ')}\n` `` (note it automatically gets a leading line end). Each member is formatted by itself and the bullet is not formatted. So you would see the above message printed as:
|
||||
|
||||

|
|
@ -0,0 +1,144 @@
|
|||
# Plugin Method References
|
||||
|
||||
:::warning
|
||||
|
||||
This section is a work in progress. Anchor links or even URLs are not guaranteed to be stable.
|
||||
|
||||
:::
|
||||
|
||||
Plugin APIs are shared by themes and plugins—themes are loaded just like plugins.
|
||||
|
||||
## Plugin module {#plugin-module}
|
||||
|
||||
Every plugin is imported as a module. The module is expected to have the following members:
|
||||
|
||||
- A **default export**: the constructor function for the plugin.
|
||||
- **Named exports**: the [static methods](./static-methods.mdx) called before plugins are initialized.
|
||||
|
||||
## Plugin constructor {#plugin-constructor}
|
||||
|
||||
The plugin module's default export is a constructor function with the signature `(context: LoadContext, options: PluginOptions) => Plugin | Promise<Plugin>`.
|
||||
|
||||
### `context` {#context}
|
||||
|
||||
`context` is plugin-agnostic, and the same object will be passed into all plugins used for a Docusaurus website. The `context` object contains the following fields:
|
||||
|
||||
```ts
|
||||
type LoadContext = {
|
||||
siteDir: string;
|
||||
generatedFilesDir: string;
|
||||
siteConfig: DocusaurusConfig;
|
||||
outDir: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
```
|
||||
|
||||
### `options` {#options}
|
||||
|
||||
`options` are the [second optional parameter when the plugins are used](../../using-plugins.mdx#configuring-plugins). `options` are plugin-specific and are specified by users when they use them in `docusaurus.config.js`. If there's a [`validateOptions`](./static-methods.mdx#validateOptions) function exported, the `options` will be validated and normalized beforehand.
|
||||
|
||||
Alternatively, if a preset contains the plugin, the preset will then be in charge of passing the correct options into the plugin. It is up to the individual plugin to define what options it takes.
|
||||
|
||||
## Example {#example}
|
||||
|
||||
Here's a mental model for a presumptuous plugin implementation.
|
||||
|
||||
```js
|
||||
// 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.
|
||||
export default async function myPlugin(context, opts) {
|
||||
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
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function validateOptions({options, validate}) {
|
||||
const validatedOptions = validate(myValidationSchema, options);
|
||||
return validatedOptions;
|
||||
}
|
||||
|
||||
export function validateThemeConfig({themeConfig, validate}) {
|
||||
const validatedThemeConfig = validate(myValidationSchema, options);
|
||||
return validatedThemeConfig;
|
||||
}
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
label: Plugin method references
|
||||
position: 1
|
|
@ -0,0 +1,132 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Extending infrastructure
|
||||
|
||||
Docusaurus has some infrastructure like hot reloading, CLI, and swizzling, that can be extended by external plugins.
|
||||
|
||||
## `getPathsToWatch()` {#getPathsToWatch}
|
||||
|
||||
Specifies the paths to watch for plugins and themes. The paths are watched by the dev server so that the plugin lifecycles are reloaded when contents in the watched paths change. Note that the plugins and themes modules are initially called with `context` and `options` from Node, which you may use to find the necessary directory information about the site.
|
||||
|
||||
Use this for files that are consumed server-side, because theme files are automatically watched by Webpack dev server.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
import path from 'path';
|
||||
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// highlight-start
|
||||
getPathsToWatch() {
|
||||
const contentPath = path.resolve(context.siteDir, options.path);
|
||||
return [`${contentPath}/**/*.{ts,tsx}`];
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `extendCli(cli)` {#extendCli}
|
||||
|
||||
Register an extra command to enhance the CLI of Docusaurus. `cli` is a [commander](https://www.npmjs.com/package/commander/v/5.1.0) object.
|
||||
|
||||
:::warning
|
||||
|
||||
The commander version matters! We use commander v5, and make sure you are referring to the right version documentation for available APIs.
|
||||
|
||||
:::
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// highlight-start
|
||||
extendCli(cli) {
|
||||
cli
|
||||
.command('roll')
|
||||
.description('Roll a random number between 1 and 1000')
|
||||
.action(() => {
|
||||
console.log(Math.floor(Math.random() * 1000 + 1));
|
||||
});
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `getThemePath()` {#getThemePath}
|
||||
|
||||
Returns the path to the directory where the theme components can be found. When your users call `swizzle`, `getThemePath` is called and its returned path is used to find your theme components. Relative paths are resolved against the folder containing the entry point.
|
||||
|
||||
For example, your `getThemePath` can be:
|
||||
|
||||
```js title="my-theme/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-theme',
|
||||
// highlight-start
|
||||
getThemePath() {
|
||||
return './theme';
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `getTypeScriptThemePath()` {#getTypeScriptThemePath}
|
||||
|
||||
Similar to `getThemePath()`, it should return the path to the directory where the source code of TypeScript theme components can be found. This path is purely for swizzling TypeScript theme components, and theme components under this path will **not** be resolved by Webpack. Therefore, it is not a replacement for `getThemePath()`. Typically, you can make the path returned by `getTypeScriptThemePath()` be your source directory, and make the path returned by `getThemePath()` be the compiled JavaScript output.
|
||||
|
||||
:::tip
|
||||
|
||||
For TypeScript theme authors: you are strongly advised to make your compiled output as human-readable as possible. Only strip type annotations and don't transpile any syntaxes, because they will be handled by Webpack's Babel loader based on the targeted browser versions.
|
||||
|
||||
You should also format these files with Prettier. Remember—JS files can and will be directly consumed by your users.
|
||||
|
||||
:::
|
||||
|
||||
Example:
|
||||
|
||||
```js title="my-theme/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-theme',
|
||||
// highlight-start
|
||||
getThemePath() {
|
||||
// Where compiled JavaScript output lives
|
||||
return '../lib/theme';
|
||||
},
|
||||
getTypeScriptThemePath() {
|
||||
// Where TypeScript source code lives
|
||||
return '../src/theme';
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `getSwizzleComponentList()` {#getSwizzleComponentList}
|
||||
|
||||
**This is a static method, not attached to any plugin instance.**
|
||||
|
||||
Returns a list of stable components that are considered safe for swizzling. These components will be swizzlable without `--danger`. All components are considered unstable by default. If an empty array is returned, all components are considered unstable. If `undefined` is returned, all components are considered stable.
|
||||
|
||||
```js title="my-theme/src/index.js"
|
||||
export function getSwizzleComponentList() {
|
||||
return [
|
||||
'CodeBlock',
|
||||
'DocSidebar',
|
||||
'Footer',
|
||||
'NotFound',
|
||||
'SearchBar',
|
||||
'hooks/useTheme',
|
||||
'prism-include-languages',
|
||||
];
|
||||
}
|
||||
```
|
|
@ -0,0 +1,121 @@
|
|||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# I18n lifecycles
|
||||
|
||||
Plugins use these lifecycles to load i18n-related data.
|
||||
|
||||
## `getTranslationFiles({content})` {#getTranslationFiles}
|
||||
|
||||
Plugins declare the JSON translation files they want to use.
|
||||
|
||||
Returns translation files `{path: string, content: ChromeI18nJSON}`:
|
||||
|
||||
- `path`: relative to the plugin localized folder `i18n/[locale]/[pluginName]`. Extension `.json` should be omitted to remain generic.
|
||||
- `content`: using the Chrome i18n JSON format.
|
||||
|
||||
These files will be written by the [`write-translations` CLI](../../cli.mdx#docusaurus-write-translations-sitedir) to the plugin i18n subfolder, and will be read in the appropriate locale before calling [`translateContent()`](#translateContent) and [`translateThemeConfig()`](#translateThemeConfig)
|
||||
|
||||
Example:
|
||||
|
||||
```js title="my-plugin.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
// highlight-start
|
||||
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,
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `translateContent({content,translationFiles})` {#translateContent}
|
||||
|
||||
Translate the plugin content, using the localized translation files.
|
||||
|
||||
Returns the localized plugin content.
|
||||
|
||||
The `contentLoaded()` lifecycle will be called with the localized plugin content returned by `translateContent()`.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="my-plugin.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
// highlight-start
|
||||
translateContent({content, translationFiles}) {
|
||||
const myTranslationFile = translationFiles.find(
|
||||
(f) => f.path === 'myTranslationFile',
|
||||
);
|
||||
return {
|
||||
...content,
|
||||
someContentLabel: myTranslationFile.someContentLabel.message,
|
||||
};
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `translateThemeConfig({themeConfig,translationFiles})` {#translateThemeConfig}
|
||||
|
||||
Translate the site `themeConfig` labels, using the localized translation files.
|
||||
|
||||
Returns the localized `themeConfig`.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="my-plugin.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-theme',
|
||||
// highlight-start
|
||||
translateThemeConfig({themeConfig, translationFiles}) {
|
||||
const myTranslationFile = translationFiles.find(
|
||||
(f) => f.path === 'myTranslationFile',
|
||||
);
|
||||
return {
|
||||
...themeConfig,
|
||||
someThemeConfigLabel: myTranslationFile.someThemeConfigLabel.message,
|
||||
};
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `async getDefaultCodeTranslationMessages()` {#getDefaultCodeTranslationMessages}
|
||||
|
||||
Themes using the `<Translate>` API can provide default code translation messages.
|
||||
|
||||
It should return messages in `Record<string, string>`, where keys are translation IDs and values are messages (without the description) localized using the site's current locale.
|
||||
|
||||
Example:
|
||||
|
||||
```js title="my-plugin.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'my-theme',
|
||||
// highlight-start
|
||||
async getDefaultCodeTranslationMessages() {
|
||||
return readJsonFile(`${context.i18n.currentLocale}.json`);
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
|
@ -0,0 +1,492 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
toc_max_heading_level: 4
|
||||
---
|
||||
|
||||
# Lifecycle APIs
|
||||
|
||||
During the build, plugins are loaded in parallel to fetch their own contents and render them to routes. Plugins may also configure webpack or post-process the generated files.
|
||||
|
||||
## `async loadContent()` {#loadContent}
|
||||
|
||||
Plugins should use this lifecycle to fetch from data sources (filesystem, remote API, headless CMS, etc.) or do some server processing. The return value is the content it needs.
|
||||
|
||||
For example, this plugin below returns a random integer between 1 and 10 as content.
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// highlight-start
|
||||
async loadContent() {
|
||||
return 1 + Math.floor(Math.random() * 10);
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `async contentLoaded({content, actions})` {#contentLoaded}
|
||||
|
||||
The data that was loaded in `loadContent` will be consumed in `contentLoaded`. It can be rendered to routes, registered as global data, etc.
|
||||
|
||||
### `content` {#content}
|
||||
|
||||
`contentLoaded` will be called _after_ `loadContent` is done. The return value of `loadContent()` will be passed to `contentLoaded` as `content`.
|
||||
|
||||
### `actions` {#actions}
|
||||
|
||||
`actions` contain three functions:
|
||||
|
||||
#### `addRoute(config: RouteConfig): void` {#addRoute}
|
||||
|
||||
Create a route to add to the website.
|
||||
|
||||
```ts
|
||||
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>` {#createData}
|
||||
|
||||
A declarative callback to create static data (generally JSON or string) which can later be provided to your routes as props. Takes the file name and data to be stored, and returns the actual data file's path.
|
||||
|
||||
For example, this plugin below creates a `/friends` page which displays `Your friends are: Yangshun, Sebastien`:
|
||||
|
||||
```jsx title="website/src/components/Friends.js"
|
||||
import React from 'react';
|
||||
|
||||
export default function FriendsComponent({friends}) {
|
||||
return <div>Your friends are {friends.join(',')}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
```js title="docusaurus-friends-plugin/src/index.js"
|
||||
export default function friendsPlugin(context, options) {
|
||||
return {
|
||||
name: 'docusaurus-friends-plugin',
|
||||
// highlight-start
|
||||
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,
|
||||
});
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### `setGlobalData(data: any): void` {#setGlobalData}
|
||||
|
||||
This function permits one to create some global plugin data that can be read from any page, including the pages created by other plugins, and your theme layout.
|
||||
|
||||
This data becomes accessible to your client-side/theme code through the [`useGlobalData`](../../docusaurus-core.mdx#useGlobalData) and [`usePluginData`](../../docusaurus-core.mdx#usePluginData) hooks.
|
||||
|
||||
:::warning
|
||||
|
||||
Global data is... global: its size affects the loading time of all pages of your site, so try to keep it small. Prefer `createData` and page-specific data whenever possible.
|
||||
|
||||
:::
|
||||
|
||||
For example, this plugin below creates a `/friends` page which displays `Your friends are: Yangshun, Sebastien`:
|
||||
|
||||
```jsx title="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>;
|
||||
}
|
||||
```
|
||||
|
||||
```js title="docusaurus-friends-plugin/src/index.js"
|
||||
export default function friendsPlugin(context, options) {
|
||||
return {
|
||||
name: 'docusaurus-friends-plugin',
|
||||
// highlight-start
|
||||
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,
|
||||
});
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `configureWebpack(config, isServer, utils, content)` {#configureWebpack}
|
||||
|
||||
Modifies the internal webpack config. If the return value is a JavaScript object, it will be merged into the final config using [`webpack-merge`](https://github.com/survivejs/webpack-merge). If it is a function, it will be called and receive `config` as the first argument and an `isServer` flag as the second argument.
|
||||
|
||||
:::warning
|
||||
|
||||
The API of `configureWebpack` will be modified in the future to accept an object (`configureWebpack({config, isServer, utils, content})`)
|
||||
|
||||
:::
|
||||
|
||||
### `config` {#config}
|
||||
|
||||
`configureWebpack` is called with `config` generated according to client/server build. You may treat this as the base config to be merged with.
|
||||
|
||||
### `isServer` {#isServer}
|
||||
|
||||
`configureWebpack` will be called both in server build and in client build. The server build receives `true` and the client build receives `false` as `isServer`.
|
||||
|
||||
### `utils` {#utils}
|
||||
|
||||
`configureWebpack` also receives an util object:
|
||||
|
||||
- `getStyleLoaders(isServer: boolean, cssOptions: {[key: string]: any}): Loader[]`
|
||||
- `getJSLoader(isServer: boolean, cacheOptions?: {}): Loader | null`
|
||||
|
||||
You may use them to return your webpack configuration conditionally.
|
||||
|
||||
For example, this plugin below modify the webpack config to transpile `.foo` files.
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'custom-docusaurus-plugin',
|
||||
// highlight-start
|
||||
configureWebpack(config, isServer, utils) {
|
||||
const {getJSLoader} = utils;
|
||||
return {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.foo$/,
|
||||
use: [getJSLoader(isServer), 'my-custom-webpack-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### `content` {#content-1}
|
||||
|
||||
`configureWebpack` will be called both with the content loaded by the plugin.
|
||||
|
||||
### Merge strategy {#merge-strategy}
|
||||
|
||||
We merge the Webpack configuration parts of plugins into the global Webpack config using [webpack-merge](https://github.com/survivejs/webpack-merge).
|
||||
|
||||
It is possible to specify the merge strategy. For example, if you want a webpack rule to be prepended instead of appended:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'custom-docusaurus-plugin',
|
||||
configureWebpack(config, isServer, utils) {
|
||||
return {
|
||||
// highlight-start
|
||||
mergeStrategy: {'module.rules': 'prepend'},
|
||||
module: {rules: [myRuleToPrepend]},
|
||||
// highlight-end
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Read the [webpack-merge strategy doc](https://github.com/survivejs/webpack-merge#merging-with-strategies) for more details.
|
||||
|
||||
### Configuring dev server {#configuring-dev-server}
|
||||
|
||||
The dev server can be configured through returning a `devServer` field.
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'custom-docusaurus-plugin',
|
||||
configureWebpack(config, isServer, utils) {
|
||||
return {
|
||||
// highlight-start
|
||||
devServer: {
|
||||
open: '/docs', // Opens localhost:3000/docs instead of localhost:3000/
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `configurePostCss(options)` {#configurePostCss}
|
||||
|
||||
Modifies [`postcssOptions` of `postcss-loader`](https://webpack.js.org/loaders/postcss-loader/#postcssoptions) during the generation of the client bundle.
|
||||
|
||||
Should return the mutated `postcssOptions`.
|
||||
|
||||
By default, `postcssOptions` looks like this:
|
||||
|
||||
```js
|
||||
const postcssOptions = {
|
||||
ident: 'postcss',
|
||||
plugins: [require('autoprefixer')],
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// highlight-start
|
||||
configurePostCss(postcssOptions) {
|
||||
// Appends new PostCSS plugin.
|
||||
postcssOptions.plugins.push(require('postcss-import'));
|
||||
return postcssOptions;
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `postBuild(props)` {#postBuild}
|
||||
|
||||
Called when a (production) build finishes.
|
||||
|
||||
```ts
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// highlight-start
|
||||
async postBuild({siteConfig = {}, routesPaths = [], outDir}) {
|
||||
// Print out to console all the rendered routes.
|
||||
routesPaths.map((route) => {
|
||||
console.log(route);
|
||||
});
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## `injectHtmlTags({content})` {#injectHtmlTags}
|
||||
|
||||
Inject head and/or body HTML tags to Docusaurus generated HTML.
|
||||
|
||||
`injectHtmlTags` will be called both with the content loaded by the plugin.
|
||||
|
||||
```ts
|
||||
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;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus-plugin/src/index.js"
|
||||
export default function (context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
loadContent: async () => {
|
||||
return {remoteHeadTags: await fetchHeadTagsFromAPI()};
|
||||
},
|
||||
// highlight-start
|
||||
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>`],
|
||||
};
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Tags will be added as follows:
|
||||
|
||||
- `headTags` will be inserted before the closing `</head>` tag after scripts added by config.
|
||||
- `preBodyTags` will be inserted after the opening `<body>` tag before any child elements.
|
||||
- `postBodyTags` will be inserted before the closing `</body>` tag after all child elements.
|
||||
|
||||
## `getClientModules()` {#getClientModules}
|
||||
|
||||
Returns an array of paths to the [client modules](../../advanced/client.mdx#client-modules) that are to be imported into the client bundle.
|
||||
|
||||
As an example, to make your theme load a `customCss` or `customJs` file path from `options` passed in by the user:
|
||||
|
||||
```js title="my-theme/src/index.js"
|
||||
export default function (context, options) {
|
||||
const {customCss, customJs} = options || {};
|
||||
return {
|
||||
name: 'name-of-my-theme',
|
||||
// highlight-start
|
||||
getClientModules() {
|
||||
return [customCss, customJs];
|
||||
},
|
||||
// highlight-end
|
||||
};
|
||||
}
|
||||
```
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Static methods
|
||||
|
||||
Static methods are not part of the plugin instance—they are attached to the constructor function. These methods are used to validate and normalize the plugin options and theme config, which are then used as constructor parameters to initialize the plugin instance.
|
||||
|
||||
## `validateOptions({options, validate})` {#validateOptions}
|
||||
|
||||
Returns validated and normalized options for the plugin. This method is called before the plugin is initialized. You must return the options since they will be passed to the plugin during initialization.
|
||||
|
||||
### `options` {#options}
|
||||
|
||||
`validateOptions` is called with `options` passed to plugin for validation and normalization.
|
||||
|
||||
### `validate` {#validate}
|
||||
|
||||
`validateOptions` is called with `validate` function which takes a **[Joi](https://www.npmjs.com/package/joi)** schema and options as the arguments, returns validated and normalized options. `validate` will automatically handle error and validation config.
|
||||
|
||||
:::tip
|
||||
|
||||
[Joi](https://www.npmjs.com/package/joi) is recommended for validation and normalization of options.
|
||||
|
||||
To avoid mixing Joi versions, use `import {Joi} from '@docusaurus/utils-validation'`
|
||||
|
||||
:::
|
||||
|
||||
If you don't use **[Joi](https://www.npmjs.com/package/joi)** for validation you can throw an Error in case of invalid options and return options in case of success.
|
||||
|
||||
```js title="my-plugin/src/index.js"
|
||||
export default function myPlugin(context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// rest of methods
|
||||
};
|
||||
}
|
||||
|
||||
// highlight-start
|
||||
export function validateOptions({options, validate}) {
|
||||
const validatedOptions = validate(myValidationSchema, options);
|
||||
return validatedOptions;
|
||||
}
|
||||
// highlight-end
|
||||
```
|
||||
|
||||
## `validateThemeConfig({themeConfig, validate})` {#validateThemeConfig}
|
||||
|
||||
Return validated and normalized configuration for the theme.
|
||||
|
||||
### `themeConfig` {#themeConfig}
|
||||
|
||||
`validateThemeConfig` is called with `themeConfig` provided in `docusaurus.config.js` for validation and normalization.
|
||||
|
||||
### `validate` {#validate-1}
|
||||
|
||||
`validateThemeConfig` is called with `validate` function which takes a **[Joi](https://www.npmjs.com/package/joi)** schema and `themeConfig` as the arguments, returns validated and normalized options. `validate` will automatically handle error and validation config.
|
||||
|
||||
:::tip
|
||||
|
||||
[Joi](https://www.npmjs.com/package/joi) is recommended for validation and normalization of theme config.
|
||||
|
||||
To avoid mixing Joi versions, use `import {Joi} from '@docusaurus/utils-validation'`
|
||||
|
||||
:::
|
||||
|
||||
If you don't use **[Joi](https://www.npmjs.com/package/joi)** for validation you can throw an Error in case of invalid options.
|
||||
|
||||
```js title="my-theme/src/index.js"
|
||||
export default function myPlugin(context, options) {
|
||||
return {
|
||||
name: 'docusaurus-plugin',
|
||||
// rest of methods
|
||||
};
|
||||
}
|
||||
|
||||
// highlight-start
|
||||
export function validateThemeConfig({themeConfig, validate}) {
|
||||
const validatedThemeConfig = validate(myValidationSchema, options);
|
||||
return validatedThemeConfig;
|
||||
}
|
||||
// highlight-end
|
||||
```
|
|
@ -0,0 +1,5 @@
|
|||
label: Plugins
|
||||
position: 2
|
||||
link:
|
||||
type: doc
|
||||
id: api/plugins/plugins-overview # Dogfood using a "qualified id"
|
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
sidebar_position: 0
|
||||
id: plugins-overview
|
||||
sidebar_label: Plugins overview
|
||||
slug: /api/plugins
|
||||
---
|
||||
|
||||
# Docusaurus plugins
|
||||
|
||||
We provide official Docusaurus plugins.
|
||||
|
||||
## Content plugins {#content-plugins}
|
||||
|
||||
These plugins are responsible for loading your site's content, and creating pages for your theme to render.
|
||||
|
||||
- [@docusaurus/plugin-content-docs](./plugin-content-docs.mdx)
|
||||
- [@docusaurus/plugin-content-blog](./plugin-content-blog.mdx)
|
||||
- [@docusaurus/plugin-content-pages](./plugin-content-pages.mdx)
|
||||
|
||||
## Behavior plugins {#behavior-plugins}
|
||||
|
||||
These plugins will add a useful behavior to your Docusaurus site.
|
||||
|
||||
- [@docusaurus/plugin-debug](./plugin-debug.mdx)
|
||||
- [@docusaurus/plugin-sitemap](./plugin-sitemap.mdx)
|
||||
- [@docusaurus/plugin-pwa](./plugin-pwa.mdx)
|
||||
- [@docusaurus/plugin-client-redirects](./plugin-client-redirects.mdx)
|
||||
- [@docusaurus/plugin-ideal-image](./plugin-ideal-image.mdx)
|
||||
- [@docusaurus/plugin-google-analytics](./plugin-google-analytics.mdx)
|
||||
- [@docusaurus/plugin-google-gtag](./plugin-google-gtag.mdx)
|
|
@ -0,0 +1,127 @@
|
|||
---
|
||||
sidebar_position: 4
|
||||
slug: /api/plugins/@docusaurus/plugin-client-redirects
|
||||
---
|
||||
|
||||
# 📦 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 redirect the user to your existing Docusaurus pages with JavaScript.
|
||||
|
||||
:::warning production only
|
||||
|
||||
This plugin is always inactive in development and **only active in production** because it works on the build output.
|
||||
|
||||
:::
|
||||
|
||||
:::warning
|
||||
|
||||
It is better to use server-side redirects whenever possible.
|
||||
|
||||
Before using this plugin, you should look if your hosting provider doesn't offer this feature.
|
||||
|
||||
:::
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/plugin-client-redirects
|
||||
```
|
||||
|
||||
## Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| 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` | <code>[RedirectRule](#RedirectRule)[]</code> | `[]` | The list of redirect rules. |
|
||||
| `createRedirects` | <code>[CreateRedirectsFn](#CreateRedirectsFn)</code> | `undefined` | A callback to create a redirect rule. Docusaurus query this callback against every path it has created, and use its return value to output more paths. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
This plugin will also read the [`siteConfig.onDuplicateRoutes`](../docusaurus.config.js.mdx#onDuplicateRoutes) config to adjust its logging level when multiple files will be emitted to the same location.
|
||||
|
||||
:::
|
||||
|
||||
### Types {#types}
|
||||
|
||||
#### `RedirectRule` {#RedirectRule}
|
||||
|
||||
```ts
|
||||
type RedirectRule = {
|
||||
to: string;
|
||||
from: string | string[];
|
||||
};
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
The idea of "from" and "to" is central in this plugin. "From" means a path that you want to _create_, i.e. an extra HTML file that will be written; "to" means a path to want to redirect _to_, usually a route that Docusaurus already knows about.
|
||||
|
||||
This is why you can have multiple "from" for the same "to": we will create multiple HTML files that all redirect to the same destination. On the other hand, one "from" can never have more than one "to": the written HTML file needs to have a determinate destination.
|
||||
|
||||
:::
|
||||
|
||||
#### `CreateRedirectsFn` {#CreateRedirectsFn}
|
||||
|
||||
```ts
|
||||
// The parameter `path` is a route that Docusaurus has already created. It can
|
||||
// be seen as the "to", and your return value is the "from". Returning a falsy
|
||||
// value will not create any redirect pages for this particular path.
|
||||
type CreateRedirectsFn = (path: string) => string[] | string | null | undefined;
|
||||
```
|
||||
|
||||
### Example configuration {#ex-config}
|
||||
|
||||
Here's an example configuration:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
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/newDoc',
|
||||
from: '/docs/oldDoc',
|
||||
},
|
||||
// Redirect from multiple old paths to the new path
|
||||
{
|
||||
to: '/docs/newDoc2',
|
||||
from: ['/docs/oldDocFrom2019', '/docs/legacyDocFrom2016'],
|
||||
},
|
||||
],
|
||||
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
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
|
@ -0,0 +1,307 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
slug: /api/plugins/@docusaurus/plugin-content-blog
|
||||
---
|
||||
|
||||
# 📦 plugin-content-blog
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
Provides the [Blog](blog.mdx) feature and is the default blog plugin for Docusaurus.
|
||||
|
||||
:::warning 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
|
||||
npm install --save @docusaurus/plugin-content-blog
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
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](../../using-plugins.mdx#docusauruspreset-classic).
|
||||
|
||||
:::
|
||||
|
||||
## Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | `string` | `'blog'` | Path to the blog content directory on the file system, relative to site dir. |
|
||||
| `editUrl` | <code>string \| [EditUrlFn](#EditUrlFn)</code> | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. |
|
||||
| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. |
|
||||
| `blogTitle` | `string` | `'Blog'` | Blog page title for better SEO. |
|
||||
| `blogDescription` | `string` | `'Blog'` | Blog page meta description for better SEO. |
|
||||
| `blogSidebarCount` | <code>number \| 'ALL'</code> | `5` | Number of blog post elements to show in the blog sidebar. `'ALL'` to show all blog posts; `0` to disable. |
|
||||
| `blogSidebarTitle` | `string` | `'Recent posts'` | Title of the blog sidebar. |
|
||||
| `routeBasePath` | `string` | `'blog'` | URL route for the blog section of your site. **DO NOT** include a trailing slash. Use `/` to put the blog at root path. |
|
||||
| `tagsBasePath` | `string` | `'tags'` | URL route for the tags section of your blog. Will be appended to `routeBasePath`. |
|
||||
| `pageBasePath` | `string` | `'page'` | URL route for the pages section of your blog. Will be appended to `routeBasePath`. |
|
||||
| `archiveBasePath` | <code>string \| null</code> | `'archive'` | URL route for the archive section of your blog. Will be appended to `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to disable generation of archive. |
|
||||
| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. |
|
||||
| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. |
|
||||
| `postsPerPage` | <code>number \| 'ALL'</code> | `10` | Number of posts to show per page in the listing page. Use `'ALL'` to display all posts on one listing page. |
|
||||
| `blogListComponent` | `string` | `'@theme/BlogListPage'` | Root component of the blog listing page. |
|
||||
| `blogPostComponent` | `string` | `'@theme/BlogPostPage'` | Root component of each blog post page. |
|
||||
| `blogTagsListComponent` | `string` | `'@theme/BlogTagsListPage'` | Root component of the tags list page. |
|
||||
| `blogTagsPostsComponent` | `string` | `'@theme/BlogTagsPostsPage'` | Root component of the "posts containing tag" page. |
|
||||
| `blogArchiveComponent` | `string` | `'@theme/BlogArchivePage'` | Root component of the blog archive page. |
|
||||
| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. |
|
||||
| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. |
|
||||
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
|
||||
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
|
||||
| `truncateMarker` | `RegExp` | `/<!--\s*truncate\s*-->/` \| `\{\/\*\s*truncate\s*\*\/\}/` | Truncate marker marking where the summary ends. |
|
||||
| `showReadingTime` | `boolean` | `true` | Show estimated reading time for the blog post. |
|
||||
| `readingTime` | `ReadingTimeFn` | The default reading time | A callback to customize the reading time number displayed. |
|
||||
| `authorsMapPath` | `string` | `'authors.yml'` | Path to the authors map file, relative to the blog content directory. |
|
||||
| `feedOptions` | _See below_ | `{type: ['rss', 'atom']}` | Blog feed. |
|
||||
| `feedOptions.type` | <code>[FeedType](#FeedType) \| [FeedType](#FeedType)[] \| 'all' \| null</code> | **Required** | Type of feed to be generated. Use `null` to disable generation. |
|
||||
| `feedOptions.createFeedItems` | <code>[CreateFeedItemsFn](#CreateFeedItemsFn) \| undefined</code> | `undefined` | An optional function which can be used to transform and / or filter the items in the feed. |
|
||||
| `feedOptions.limit` | `number \| null \| false` | `20` | Limits the feed to the specified number of posts, `false` or `null` for all entries. Defaults to `20`. |
|
||||
| `feedOptions.title` | `string` | `siteConfig.title` | Title of the feed. |
|
||||
| `feedOptions.description` | `string` | <code>\`$\{siteConfig.title} Blog\`</code> | Description of the feed. |
|
||||
| `feedOptions.copyright` | `string` | `undefined` | Copyright message. |
|
||||
| `feedOptions.language` | `string` (See [documentation](http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes) for possible values) | `undefined` | Language metadata of the feed. |
|
||||
| `sortPosts` | <code>'descending' \| 'ascending' </code> | `'descending'` | Governs the direction of blog post sorting. |
|
||||
| `processBlogPosts` | <code>[ProcessBlogPostsFn](#ProcessBlogPostsFn)</code> | `undefined` | An optional function which can be used to transform blog posts (filter, modify, delete, etc...). |
|
||||
| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the blog post. |
|
||||
| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the blog post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### Types {#types}
|
||||
|
||||
#### `EditUrlFn` {#EditUrlFn}
|
||||
|
||||
```ts
|
||||
type EditUrlFunction = (params: {
|
||||
blogDirPath: string;
|
||||
blogPath: string;
|
||||
permalink: string;
|
||||
locale: string;
|
||||
}) => string | undefined;
|
||||
```
|
||||
|
||||
#### `ReadingTimeFn` {#ReadingTimeFn}
|
||||
|
||||
```ts
|
||||
type ReadingTimeOptions = {
|
||||
wordsPerMinute: number;
|
||||
wordBound: (char: string) => boolean;
|
||||
};
|
||||
|
||||
type ReadingTimeCalculator = (params: {
|
||||
content: string;
|
||||
frontMatter?: BlogPostFrontMatter & Record<string, unknown>;
|
||||
options?: ReadingTimeOptions;
|
||||
}) => number;
|
||||
|
||||
type ReadingTimeFn = (params: {
|
||||
content: string;
|
||||
frontMatter: BlogPostFrontMatter & Record<string, unknown>;
|
||||
defaultReadingTime: ReadingTimeCalculator;
|
||||
}) => number | undefined;
|
||||
```
|
||||
|
||||
#### `FeedType` {#FeedType}
|
||||
|
||||
```ts
|
||||
type FeedType = 'rss' | 'atom' | 'json';
|
||||
```
|
||||
|
||||
#### `CreateFeedItemsFn` {#CreateFeedItemsFn}
|
||||
|
||||
```ts
|
||||
type CreateFeedItemsFn = (params: {
|
||||
blogPosts: BlogPost[];
|
||||
siteConfig: DocusaurusConfig;
|
||||
outDir: string;
|
||||
defaultCreateFeedItemsFn: CreateFeedItemsFn;
|
||||
}) => Promise<BlogFeedItem[]>;
|
||||
```
|
||||
|
||||
#### `ProcessBlogPostsFn` {#ProcessBlogPostsFn}
|
||||
|
||||
```ts
|
||||
type ProcessBlogPostsFn = (params: {
|
||||
blogPosts: BlogPost[];
|
||||
}) => Promise<void | BlogPost[]>;
|
||||
```
|
||||
|
||||
### 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 Options: blog
|
||||
// Plugin Options: @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}) =>
|
||||
`https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`,
|
||||
editLocalizedFiles: false,
|
||||
blogTitle: 'Blog title',
|
||||
blogDescription: 'Blog',
|
||||
blogSidebarCount: 5,
|
||||
blogSidebarTitle: 'All our posts',
|
||||
routeBasePath: 'blog',
|
||||
include: ['**/*.{md,mdx}'],
|
||||
exclude: [
|
||||
'**/_*.{js,jsx,ts,tsx,md,mdx}',
|
||||
'**/_*/**',
|
||||
'**/*.test.{js,jsx,ts,tsx}',
|
||||
'**/__tests__/**',
|
||||
],
|
||||
postsPerPage: 10,
|
||||
blogListComponent: '@theme/BlogListPage',
|
||||
blogPostComponent: '@theme/BlogPostPage',
|
||||
blogTagsListComponent: '@theme/BlogTagsListPage',
|
||||
blogTagsPostsComponent: '@theme/BlogTagsPostsPage',
|
||||
remarkPlugins: [require('./my-remark-plugin')],
|
||||
rehypePlugins: [],
|
||||
beforeDefaultRemarkPlugins: [],
|
||||
beforeDefaultRehypePlugins: [],
|
||||
truncateMarker: /<!--\s*(truncate)\s*-->/,
|
||||
showReadingTime: true,
|
||||
feedOptions: {
|
||||
type: '',
|
||||
title: '',
|
||||
description: '',
|
||||
copyright: '',
|
||||
language: undefined,
|
||||
createFeedItems: async (params) => {
|
||||
const {blogPosts, defaultCreateFeedItems, ...rest} = params;
|
||||
return defaultCreateFeedItems({
|
||||
// keep only the 10 most recent blog posts in the feed
|
||||
blogPosts: blogPosts.filter((item, index) => index < 10),
|
||||
...rest,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Markdown front matter {#markdown-front-matter}
|
||||
|
||||
Markdown documents can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side.
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `authors` | `Authors` | `undefined` | List of blog post authors (or unique author). Read the [`authors` guide](../../blog.mdx#blog-post-authors) for more explanations. Prefer `authors` over the `author_*` front matter fields, even for single author blog posts. |
|
||||
| `author` | `string` | `undefined` | ⚠️ Prefer using `authors`. The blog post author's name. |
|
||||
| `author_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL that the author's name will be linked to. This could be a GitHub, Twitter, Facebook profile URL, etc. |
|
||||
| `author_image_url` | `string` | `undefined` | ⚠️ Prefer using `authors`. The URL to the author's thumbnail image. |
|
||||
| `author_title` | `string` | `undefined` | ⚠️ Prefer using `authors`. A description of the author. |
|
||||
| `title` | `string` | Markdown title | The blog post title. |
|
||||
| `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. |
|
||||
| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. |
|
||||
| `draft` | `boolean` | `false` | Draft blog posts will only be available during development. |
|
||||
| `unlisted` | `boolean` | `false` | Unlisted blog posts will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. |
|
||||
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
|
||||
| `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. |
|
||||
| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. |
|
||||
| `keywords` | `string[]` | `undefined` | Keywords meta tag, which will become the `<meta name="keywords" content="keyword1,keyword2,..."/>` in `<head>`, used by search engines. |
|
||||
| `description` | `string` | The first line of Markdown content | The description of your document, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. |
|
||||
| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. |
|
||||
| `slug` | `string` | File path | Allows to customize the blog post URL (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-blog-post`, `slug: /my/path/to/blog/post`, slug: `/`. |
|
||||
| `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
```ts
|
||||
type FrontMatterLastUpdate = {date?: string; author?: string};
|
||||
|
||||
type Tag = string | {label: string; permalink: string};
|
||||
|
||||
// An author key references an author from the global plugin authors.yml file
|
||||
type AuthorKey = string;
|
||||
|
||||
type Author = {
|
||||
key?: AuthorKey;
|
||||
name: string;
|
||||
title?: string;
|
||||
url?: string;
|
||||
image_url?: string;
|
||||
};
|
||||
|
||||
// The front matter authors field allows various possible shapes
|
||||
type Authors = AuthorKey | Author | (AuthorKey | Author)[];
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```md
|
||||
---
|
||||
title: Welcome Docusaurus
|
||||
authors:
|
||||
- slorber
|
||||
- yangshun
|
||||
- name: Joel Marcey
|
||||
title: Co-creator of Docusaurus 1
|
||||
url: https://github.com/JoelMarcey
|
||||
image_url: https://github.com/JoelMarcey.png
|
||||
tags: [hello, docusaurus-v2]
|
||||
description: This is my first post on Docusaurus.
|
||||
image: https://i.imgur.com/mErPwqL.png
|
||||
hide_table_of_contents: false
|
||||
---
|
||||
|
||||
A Markdown blog post
|
||||
```
|
||||
|
||||
## i18n {#i18n}
|
||||
|
||||
Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first.
|
||||
|
||||
### Translation files location {#translation-files-location}
|
||||
|
||||
- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-blog`
|
||||
- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-blog-[pluginId]`
|
||||
- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir)
|
||||
- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-blog`
|
||||
|
||||
### Example file-system structure {#example-file-system-structure}
|
||||
|
||||
```bash
|
||||
website/i18n/[locale]/docusaurus-plugin-content-blog
|
||||
│
|
||||
│ # translations for website/blog
|
||||
├── authors.yml
|
||||
├── first-blog-post.md
|
||||
├── second-blog-post.md
|
||||
│
|
||||
│ # translations for the plugin options that will be rendered
|
||||
└── options.json
|
||||
```
|
|
@ -0,0 +1,368 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
slug: /api/plugins/@docusaurus/plugin-content-docs
|
||||
---
|
||||
|
||||
# 📦 plugin-content-docs
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
Provides the [Docs](../../guides/docs/docs-introduction.mdx) functionality and is the default docs plugin for Docusaurus.
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/plugin-content-docs
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
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](../../using-plugins.mdx#docusauruspreset-classic).
|
||||
|
||||
:::
|
||||
|
||||
## Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | `string` | `'docs'` | Path to the docs content directory on the file system, relative to site directory. |
|
||||
| `editUrl` | <code>string \| [EditUrlFunction](#EditUrlFunction)</code> | `undefined` | Base URL to edit your site. The final URL is computed by `editUrl + relativeDocPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. |
|
||||
| `editLocalizedFiles` | `boolean` | `false` | The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. |
|
||||
| `editCurrentVersion` | `boolean` | `false` | The edit URL will always target the current version doc instead of older versions. Ignored when `editUrl` is a function. |
|
||||
| `routeBasePath` | `string` | `'docs'` | URL route for the docs section of your site. **DO NOT** include a trailing slash. Use `/` for shipping docs without base path. |
|
||||
| `tagsBasePath` | `string` | `'tags'` | URL route for the tags list page of your site. It is prepended to the `routeBasePath`. |
|
||||
| `include` | `string[]` | `['**/*.{md,mdx}']` | Array of glob patterns matching Markdown files to be built, relative to the content path. |
|
||||
| `exclude` | `string[]` | _See example configuration_ | Array of glob patterns matching Markdown files to be excluded. Serves as refinement based on the `include` option. |
|
||||
| `sidebarPath` | <code>false \| string</code> | `undefined` | Path to sidebar configuration. Use `false` to disable sidebars, or `undefined` to create a fully autogenerated sidebar. |
|
||||
| `sidebarCollapsible` | `boolean` | `true` | Whether sidebar categories are collapsible by default. See also [Collapsible categories](/docs/sidebar/items#collapsible-categories) |
|
||||
| `sidebarCollapsed` | `boolean` | `true` | Whether sidebar categories are collapsed by default. See also [Expanded categories by default](/docs/sidebar/items#expanded-categories-by-default) |
|
||||
| `sidebarItemsGenerator` | <code>[SidebarGenerator](#SidebarGenerator)</code> | _Omitted_ | Function used to replace the sidebar items of type `'autogenerated'` with real sidebar items (docs, categories, links...). See also [Customize the sidebar items generator](/docs/sidebar/autogenerated#customize-the-sidebar-items-generator) |
|
||||
| `numberPrefixParser` | <code>boolean \| [PrefixParser](#PrefixParser)</code> | _Omitted_ | Custom parsing logic to extract number prefixes from file names. Use `false` to disable this behavior and leave the docs untouched, and `true` to use the default parser. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes) |
|
||||
| `docsRootComponent` | `string` | `'@theme/DocsRoot'` | Parent component of all the docs plugin pages (including all versions). Stays mounted when navigation between docs pages and versions. |
|
||||
| `docVersionRootComponent` | `string` | `'@theme/DocVersionLayout'` | Parent component of all docs pages of an individual version (doc pages with sidebars, tags pages). Stays mounted when navigation between pages of that specific version. |
|
||||
| `docRootComponent` | `string` | `'@theme/DocPage'` | Parent component of all doc pages with sidebars (regular docs pages, category generated index pages). Stays mounted when navigation between such pages. |
|
||||
| `docItemComponent` | `string` | `'@theme/DocItem'` | Main doc container, with TOC, pagination, etc. |
|
||||
| `docTagsListComponent` | `string` | `'@theme/DocTagsListPage'` | Root component of the tags list page |
|
||||
| `docTagDocListComponent` | `string` | `'@theme/DocTagDocListPage'` | Root component of the "docs containing tag X" page. |
|
||||
| `docCategoryGeneratedIndexComponent` | `string` | `'@theme/DocCategoryGeneratedIndexPage'` | Root component of the generated category index page. |
|
||||
| `remarkPlugins` | `any[]` | `[]` | Remark plugins passed to MDX. |
|
||||
| `rehypePlugins` | `any[]` | `[]` | Rehype plugins passed to MDX. |
|
||||
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
|
||||
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
|
||||
| `showLastUpdateAuthor` | `boolean` | `false` | Whether to display the author who last updated the doc. |
|
||||
| `showLastUpdateTime` | `boolean` | `false` | Whether to display the last date the doc was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. |
|
||||
| `breadcrumbs` | `boolean` | `true` | Enable or disable the breadcrumbs on doc pages. |
|
||||
| `disableVersioning` | `boolean` | `false` | Explicitly disable versioning even when multiple versions exist. This will make the site only include the current version. Will error if `includeCurrentVersion: false` and `disableVersioning: true`. |
|
||||
| `includeCurrentVersion` | `boolean` | `true` | Include the current version of your docs. |
|
||||
| `lastVersion` | `string` | First version in `versions.json` | The version navigated to in priority and displayed by default for docs navbar items. |
|
||||
| `onlyIncludeVersions` | `string[]` | All versions available | Only include a subset of all available versions. |
|
||||
| `versions` | <code>[VersionsConfig](#VersionsConfig)</code> | `{}` | Independent customization of each version's properties. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### Types {#types}
|
||||
|
||||
#### `EditUrlFunction` {#EditUrlFunction}
|
||||
|
||||
```ts
|
||||
type EditUrlFunction = (params: {
|
||||
version: string;
|
||||
versionDocsDirPath: string;
|
||||
docPath: string;
|
||||
permalink: string;
|
||||
locale: string;
|
||||
}) => string | undefined;
|
||||
```
|
||||
|
||||
#### `PrefixParser` {#PrefixParser}
|
||||
|
||||
```ts
|
||||
type PrefixParser = (filename: string) => {
|
||||
filename: string;
|
||||
numberPrefix?: number;
|
||||
};
|
||||
```
|
||||
|
||||
#### `SidebarGenerator` {#SidebarGenerator}
|
||||
|
||||
```ts
|
||||
type SidebarGenerator = (generatorArgs: {
|
||||
/** The sidebar item with type "autogenerated" to be transformed. */
|
||||
item: {type: 'autogenerated'; dirName: string};
|
||||
/** Useful metadata for the version this sidebar belongs to. */
|
||||
version: {contentPath: string; versionName: string};
|
||||
/** All the docs of that version (unfiltered). */
|
||||
docs: {
|
||||
id: string;
|
||||
title: string;
|
||||
frontMatter: DocFrontMatter & Record<string, unknown>;
|
||||
source: string;
|
||||
sourceDirName: string;
|
||||
sidebarPosition?: number | undefined;
|
||||
}[];
|
||||
/** Number prefix parser configured for this plugin. */
|
||||
numberPrefixParser: PrefixParser;
|
||||
/** The default category index matcher which you can override. */
|
||||
isCategoryIndex: CategoryIndexMatcher;
|
||||
/**
|
||||
* key is the path relative to the doc content directory, value is the
|
||||
* category metadata file's content.
|
||||
*/
|
||||
categoriesMetadata: {[filePath: string]: CategoryMetadata};
|
||||
/**
|
||||
* Useful to re-use/enhance the default sidebar generation logic from
|
||||
* Docusaurus.
|
||||
*/
|
||||
defaultSidebarItemsGenerator: SidebarGenerator;
|
||||
// Returns an array of sidebar items — same as what you can declare in
|
||||
// sidebars.js, except for shorthands. See https://docusaurus.io/docs/sidebar/items
|
||||
}) => Promise<SidebarItem[]>;
|
||||
|
||||
type CategoryIndexMatcher = (param: {
|
||||
/** The file name, without extension */
|
||||
fileName: string;
|
||||
/**
|
||||
* The list of directories, from lowest level to highest.
|
||||
* If there's no dir name, directories is ['.']
|
||||
*/
|
||||
directories: string[];
|
||||
/** The extension, with a leading dot */
|
||||
extension: string;
|
||||
}) => boolean;
|
||||
```
|
||||
|
||||
#### `VersionsConfig` {#VersionsConfig}
|
||||
|
||||
```ts
|
||||
type VersionConfig = {
|
||||
/**
|
||||
* The base path of the version, will be appended to `baseUrl` +
|
||||
* `routeBasePath`.
|
||||
*/
|
||||
path?: string;
|
||||
/** The label of the version to be used in badges, dropdowns, etc. */
|
||||
label?: string;
|
||||
/** The banner to show at the top of a doc of that version. */
|
||||
banner?: 'none' | 'unreleased' | 'unmaintained';
|
||||
/** Show a badge with the version label at the top of each doc. */
|
||||
badge?: boolean;
|
||||
/** Prevents search engines from indexing this version */
|
||||
noIndex?: boolean;
|
||||
/** Add a custom class name to the <html> element of each doc */
|
||||
className?: string;
|
||||
};
|
||||
|
||||
type VersionsConfig = {[versionName: string]: VersionConfig};
|
||||
```
|
||||
|
||||
### 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 Options: docs
|
||||
// Plugin Options: @docusaurus/plugin-content-docs
|
||||
|
||||
const config = {
|
||||
path: 'docs',
|
||||
breadcrumbs: true,
|
||||
// Simple use-case: string editUrl
|
||||
// editUrl: 'https://github.com/facebook/docusaurus/edit/main/website/',
|
||||
// Advanced use-case: functional editUrl
|
||||
editUrl: ({versionDocsDirPath, docPath}) =>
|
||||
`https://github.com/facebook/docusaurus/edit/main/website/${versionDocsDirPath}/${docPath}`,
|
||||
editLocalizedFiles: false,
|
||||
editCurrentVersion: false,
|
||||
routeBasePath: 'docs',
|
||||
include: ['**/*.md', '**/*.mdx'],
|
||||
exclude: [
|
||||
'**/_*.{js,jsx,ts,tsx,md,mdx}',
|
||||
'**/_*/**',
|
||||
'**/*.test.{js,jsx,ts,tsx}',
|
||||
'**/__tests__/**',
|
||||
],
|
||||
sidebarPath: 'sidebars.js',
|
||||
async sidebarItemsGenerator({
|
||||
defaultSidebarItemsGenerator,
|
||||
numberPrefixParser,
|
||||
item,
|
||||
version,
|
||||
docs,
|
||||
isCategoryIndex,
|
||||
}) {
|
||||
// Use the provided data to generate a custom sidebar slice
|
||||
return [
|
||||
{type: 'doc', id: 'intro'},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorials',
|
||||
items: [
|
||||
{type: 'doc', id: 'tutorial1'},
|
||||
{type: 'doc', id: 'tutorial2'},
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
numberPrefixParser(filename) {
|
||||
// Implement your own logic to extract a potential number prefix
|
||||
const numberPrefix = findNumberPrefix(filename);
|
||||
// Prefix found: return it with the cleaned filename
|
||||
if (numberPrefix) {
|
||||
return {
|
||||
numberPrefix,
|
||||
filename: filename.replace(prefix, ''),
|
||||
};
|
||||
}
|
||||
// No number prefix found
|
||||
return {numberPrefix: undefined, filename};
|
||||
},
|
||||
docsRootComponent: '@theme/DocsRoot',
|
||||
docVersionRootComponent: '@theme/DocVersionRoot',
|
||||
docRootComponent: '@theme/DocRoot',
|
||||
docItemComponent: '@theme/DocItem',
|
||||
remarkPlugins: [require('./my-remark-plugin')],
|
||||
rehypePlugins: [],
|
||||
beforeDefaultRemarkPlugins: [],
|
||||
beforeDefaultRehypePlugins: [],
|
||||
showLastUpdateAuthor: false,
|
||||
showLastUpdateTime: false,
|
||||
disableVersioning: false,
|
||||
includeCurrentVersion: true,
|
||||
lastVersion: undefined,
|
||||
versions: {
|
||||
current: {
|
||||
label: 'Android SDK v2.0.0 (WIP)',
|
||||
path: 'android-2.0.0',
|
||||
banner: 'none',
|
||||
},
|
||||
'1.0.0': {
|
||||
label: 'Android SDK v1.0.0',
|
||||
path: 'android-1.0.0',
|
||||
banner: 'unmaintained',
|
||||
},
|
||||
},
|
||||
onlyIncludeVersions: ['current', '1.0.0', '2.0.0'],
|
||||
};
|
||||
```
|
||||
|
||||
## Markdown front matter {#markdown-front-matter}
|
||||
|
||||
Markdown documents can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side.
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `id` | `string` | file path (including folders, without the extension) | A unique document ID. |
|
||||
| `title` | `string` | Markdown title or `id` | The text title of your document. Used for the page metadata and as a fallback value in multiple places (sidebar, next/previous buttons...). Automatically added at the top of your doc if it does not contain any Markdown title. |
|
||||
| `pagination_label` | `string` | `sidebar_label` or `title` | The text used in the document next/previous buttons for this document. |
|
||||
| `sidebar_label` | `string` | `title` | The text shown in the document sidebar for this document. |
|
||||
| `sidebar_position` | `number` | Default ordering | Controls the position of a doc inside the generated sidebar slice when using `autogenerated` sidebar items. See also [Autogenerated sidebar metadata](/docs/sidebar/autogenerated#autogenerated-sidebar-metadata). |
|
||||
| `sidebar_class_name` | `string` | `undefined` | Gives the corresponding sidebar label a special class name when using autogenerated sidebars. |
|
||||
| `sidebar_custom_props` | `object` | `undefined` | Assign [custom props](../../guides/docs/sidebar/index.mdx#passing-custom-props) to the sidebar item referencing this doc |
|
||||
| `displayed_sidebar` | `string` | `undefined` | Force the display of a given sidebar when browsing the current document. Read the [multiple sidebars guide](../../guides/docs/sidebar/multiple-sidebars.mdx) for details. |
|
||||
| `hide_title` | `boolean` | `false` | Whether to hide the title at the top of the doc. It only hides a title declared through the front matter, and have no effect on a Markdown title at the top of your document. |
|
||||
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
|
||||
| `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. |
|
||||
| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. |
|
||||
| `pagination_next` | <code>string \| null</code> | Next doc in the sidebar | The ID of the documentation you want the "Next" pagination to link to. Use `null` to disable showing "Next" for this page. |
|
||||
| `pagination_prev` | <code>string \| null</code> | Previous doc in the sidebar | The ID of the documentation you want the "Previous" pagination to link to. Use `null` to disable showing "Previous" for this page. |
|
||||
| `parse_number_prefixes` | `boolean` | `numberPrefixParser` plugin option | Whether number prefix parsing is disabled on this doc. See also [Using number prefixes](/docs/sidebar/autogenerated#using-number-prefixes). |
|
||||
| `custom_edit_url` | <code>string \| null</code> | Computed using the `editUrl` plugin option | The URL for editing this document. Use `null` to disable showing "Edit this page" for this page. |
|
||||
| `keywords` | `string[]` | `undefined` | Keywords meta tag for the document page, for search engines. |
|
||||
| `description` | `string` | The first line of Markdown content | The description of your document, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. |
|
||||
| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. |
|
||||
| `slug` | `string` | File path | Allows to customize the document URL (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. |
|
||||
| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. |
|
||||
| `draft` | `boolean` | `false` | Draft documents will only be available during development. |
|
||||
| `unlisted` | `boolean` | `false` | Unlisted documents will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. |
|
||||
| `last_update` | `FrontMatterLastUpdate` | `undefined` | Allows overriding the last update author/date. Date can be any [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse). |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
```ts
|
||||
type FrontMatterLastUpdate = {date?: string; author?: string};
|
||||
|
||||
type Tag = string | {label: string; permalink: string};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```md
|
||||
---
|
||||
id: doc-markdown
|
||||
title: Docs Markdown Features
|
||||
hide_title: false
|
||||
hide_table_of_contents: false
|
||||
sidebar_label: Markdown
|
||||
sidebar_position: 3
|
||||
pagination_label: Markdown features
|
||||
custom_edit_url: https://github.com/facebook/docusaurus/edit/main/docs/api-doc-markdown.md
|
||||
description: How do I find you when I cannot solve this problem
|
||||
keywords:
|
||||
- docs
|
||||
- docusaurus
|
||||
image: https://i.imgur.com/mErPwqL.png
|
||||
slug: /myDoc
|
||||
last_update:
|
||||
date: 1/1/2000
|
||||
author: custom author name
|
||||
---
|
||||
|
||||
# Markdown Features
|
||||
|
||||
My Document Markdown content
|
||||
```
|
||||
|
||||
## i18n {#i18n}
|
||||
|
||||
Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first.
|
||||
|
||||
### Translation files location {#translation-files-location}
|
||||
|
||||
- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-docs`
|
||||
- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-docs-[pluginId]`
|
||||
- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir)
|
||||
- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-docs/[versionName]`
|
||||
|
||||
### Example file-system structure {#example-file-system-structure}
|
||||
|
||||
```bash
|
||||
website/i18n/[locale]/docusaurus-plugin-content-docs
|
||||
│
|
||||
│ # translations for website/docs
|
||||
├── current
|
||||
│ ├── api
|
||||
│ │ └── config.md
|
||||
│ └── getting-started.md
|
||||
├── current.json
|
||||
│
|
||||
│ # translations for website/versioned_docs/version-1.0.0
|
||||
├── version-1.0.0
|
||||
│ ├── api
|
||||
│ │ └── config.md
|
||||
│ └── getting-started.md
|
||||
└── version-1.0.0.json
|
||||
```
|
|
@ -0,0 +1,157 @@
|
|||
---
|
||||
sidebar_position: 3
|
||||
slug: /api/plugins/@docusaurus/plugin-content-pages
|
||||
---
|
||||
|
||||
# 📦 plugin-content-pages
|
||||
|
||||
import APITable from '@site/src/components/APITable';
|
||||
|
||||
The default pages plugin for Docusaurus. The classic template ships with this plugin with default configurations. This plugin provides [creating pages](guides/creating-pages.mdx) functionality.
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/plugin-content-pages
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
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](../../using-plugins.mdx#docusauruspreset-classic).
|
||||
|
||||
:::
|
||||
|
||||
## Configuration {#configuration}
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `path` | `string` | `'src/pages'` | Path to data on filesystem relative to site dir. Components in this directory will be automatically converted to pages. |
|
||||
| `editUrl` | <code>string \| [EditUrlFn](#EditUrlFn)</code> | `undefined` | **Only for Markdown pages**. Base URL to edit your site. The final URL is computed by `editUrl + relativePostPath`. Using a function allows more nuanced control for each file. Omitting this variable entirely will disable edit links. |
|
||||
| `editLocalizedFiles` | `boolean` | `false` | **Only for Markdown pages**. The edit URL will target the localized file, instead of the original unlocalized file. Ignored when `editUrl` is a function. |
|
||||
| `routeBasePath` | `string` | `'/'` | URL route for the pages section of your site. **DO NOT** include a trailing slash. |
|
||||
| `include` | `string[]` | `['**/*.{js,jsx,ts,tsx,md,mdx}']` | Matching files will be included and processed. |
|
||||
| `exclude` | `string[]` | _See example configuration_ | No route will be created for matching files. |
|
||||
| `mdxPageComponent` | `string` | `'@theme/MDXPage'` | Component used by each MDX page. |
|
||||
| `remarkPlugins` | `[]` | `any[]` | Remark plugins passed to MDX. |
|
||||
| `rehypePlugins` | `[]` | `any[]` | Rehype plugins passed to MDX. |
|
||||
| `beforeDefaultRemarkPlugins` | `any[]` | `[]` | Custom Remark plugins passed to MDX before the default Docusaurus Remark plugins. |
|
||||
| `beforeDefaultRehypePlugins` | `any[]` | `[]` | Custom Rehype plugins passed to MDX before the default Docusaurus Rehype plugins. |
|
||||
| `showLastUpdateAuthor` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the author who last updated the page. |
|
||||
| `showLastUpdateTime` | `boolean` | `false` | **Only for Markdown pages**. Whether to display the last date the page post was updated. This requires access to git history during the build, so will not work correctly with shallow clones (a common default for CI systems). With GitHub `actions/checkout`, use`fetch-depth: 0`. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
### Types {#types}
|
||||
|
||||
#### `EditUrlFn` {#EditUrlFn}
|
||||
|
||||
```ts
|
||||
type EditUrlFunction = (params: {
|
||||
blogDirPath: string;
|
||||
blogPath: string;
|
||||
permalink: string;
|
||||
locale: string;
|
||||
}) => string | undefined;
|
||||
```
|
||||
|
||||
### 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 Options: pages
|
||||
// Plugin Options: @docusaurus/plugin-content-pages
|
||||
|
||||
const config = {
|
||||
path: 'src/pages',
|
||||
routeBasePath: '',
|
||||
include: ['**/*.{js,jsx,ts,tsx,md,mdx}'],
|
||||
exclude: [
|
||||
'**/_*.{js,jsx,ts,tsx,md,mdx}',
|
||||
'**/_*/**',
|
||||
'**/*.test.{js,jsx,ts,tsx}',
|
||||
'**/__tests__/**',
|
||||
],
|
||||
mdxPageComponent: '@theme/MDXPage',
|
||||
remarkPlugins: [require('./my-remark-plugin')],
|
||||
rehypePlugins: [],
|
||||
beforeDefaultRemarkPlugins: [],
|
||||
beforeDefaultRehypePlugins: [],
|
||||
};
|
||||
```
|
||||
|
||||
## Markdown front matter {#markdown-front-matter}
|
||||
|
||||
Markdown pages can use the following Markdown [front matter](../../guides/markdown-features/markdown-features-intro.mdx#front-matter) metadata fields, enclosed by a line `---` on either side.
|
||||
|
||||
Accepted fields:
|
||||
|
||||
```mdx-code-block
|
||||
<APITable>
|
||||
```
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `title` | `string` | Markdown title | The blog post title. |
|
||||
| `description` | `string` | The first line of Markdown content | The description of your page, which will become the `<meta name="description" content="..."/>` and `<meta property="og:description" content="..."/>` in `<head>`, used by search engines. |
|
||||
| `keywords` | `string[]` | `undefined` | Keywords meta tag, which will become the `<meta name="keywords" content="keyword1,keyword2,..."/>` in `<head>`, used by search engines. |
|
||||
| `image` | `string` | `undefined` | Cover or thumbnail image that will be used as the `<meta property="og:image" content="..."/>` in the `<head>`, enhancing link previews on social media and messaging platforms. |
|
||||
| `wrapperClassName` | `string` | | Class name to be added to the wrapper element to allow targeting specific page content. |
|
||||
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
|
||||
| `draft` | `boolean` | `false` | Draft pages will only be available during development. |
|
||||
| `unlisted` | `boolean` | `false` | Unlisted pages will be available in both development and production. They will be "hidden" in production, not indexed, excluded from sitemaps, and can only be accessed by users having a direct link. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```md
|
||||
---
|
||||
title: Markdown Page
|
||||
description: Markdown page SEO description
|
||||
wrapperClassName: markdown-page
|
||||
hide_table_of_contents: false
|
||||
draft: true
|
||||
---
|
||||
|
||||
Markdown page content
|
||||
```
|
||||
|
||||
## i18n {#i18n}
|
||||
|
||||
Read the [i18n introduction](../../i18n/i18n-introduction.mdx) first.
|
||||
|
||||
### Translation files location {#translation-files-location}
|
||||
|
||||
- **Base path**: `website/i18n/[locale]/docusaurus-plugin-content-pages`
|
||||
- **Multi-instance path**: `website/i18n/[locale]/docusaurus-plugin-content-pages-[pluginId]`
|
||||
- **JSON files**: extracted with [`docusaurus write-translations`](../../cli.mdx#docusaurus-write-translations-sitedir)
|
||||
- **Markdown files**: `website/i18n/[locale]/docusaurus-plugin-content-pages`
|
||||
|
||||
### Example file-system structure {#example-file-system-structure}
|
||||
|
||||
```bash
|
||||
website/i18n/[locale]/docusaurus-plugin-content-pages
|
||||
│
|
||||
│ # translations for website/src/pages
|
||||
├── first-markdown-page.md
|
||||
└── second-markdown-page.md
|
||||
```
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
sidebar_position: 5
|
||||
slug: /api/plugins/@docusaurus/plugin-debug
|
||||
---
|
||||
|
||||
# 📦 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"
|
||||
export default {
|
||||
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](/__docusaurus/debug).
|
||||
|
||||
:::
|
||||
|
||||
## Installation {#installation}
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save @docusaurus/plugin-debug
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
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](../../using-plugins.mdx#docusauruspreset-classic).
|
||||
|
||||
:::
|
||||
|
||||
## 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.
|
||||
|
||||
:::
|
||||
|
||||
```mdx-code-block
|
||||
<Tabs groupId="api-config-ex">
|
||||
<TabItem value="preset" label="Preset options">
|
||||
```
|
||||
|
||||
If you use a preset, configure this plugin through the [preset options](../../using-plugins.mdx#docusauruspreset-classic):
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
// highlight-next-line
|
||||
debug: true, // This will enable the plugin in production
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
<TabItem value="plugin" label="Plugin Options">
|
||||
```
|
||||
|
||||
If you are using a standalone plugin, provide options directly to the plugin:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
export default {
|
||||
// highlight-next-line
|
||||
plugins: ['@docusaurus/plugin-debug'],
|
||||
};
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue