mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-22 05:27:00 +02:00
chore: prepare v2.0.0-beta.16 release (#6760)
This commit is contained in:
parent
17b8eded79
commit
124511f445
142 changed files with 6743 additions and 4173 deletions
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
id: create-doc
|
||||
title: Create a doc
|
||||
description: Create a Markdown Document
|
||||
slug: /create-doc
|
||||
---
|
||||
|
||||
Create a Markdown file, `greeting.md`, and place it under the `docs` directory.
|
||||
|
||||
```bash
|
||||
website # root directory of your site
|
||||
├── docs
|
||||
│ └── greeting.md
|
||||
├── src
|
||||
│ └── pages
|
||||
├── docusaurus.config.js
|
||||
├── ...
|
||||
```
|
||||
|
||||
At the top of the file, specify `id` and `title` in the front matter, so that Docusaurus will pick them up correctly when generating your site.
|
||||
|
||||
```md
|
||||
---
|
||||
id: greeting
|
||||
title: Hello
|
||||
---
|
||||
|
||||
## Hello from Docusaurus
|
||||
|
||||
Are you ready to create the documentation site for your open source project?
|
||||
|
||||
### Headers
|
||||
|
||||
will show up on the table of contents on the upper right
|
||||
|
||||
So that your users will know what this page is all about without scrolling down or even without reading too much.
|
||||
|
||||
### Only h2 and h3 will be in the TOC by default.
|
||||
|
||||
You can configure the TOC heading levels either per-document or in the theme configuration.
|
||||
|
||||
The headers are well-spaced so that the hierarchy is clear.
|
||||
|
||||
- lists will help you
|
||||
- present the key points
|
||||
- that you want your users to remember
|
||||
- and you may nest them
|
||||
- multiple times
|
||||
|
||||
### Custom id headers {#custom-id}
|
||||
|
||||
With `{#custom-id}` syntax you can set your own header id.
|
||||
```
|
||||
|
||||
This will render in the browser as follows:
|
||||
|
||||
```mdx-code-block
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
|
||||
<BrowserWindow>
|
||||
|
||||
<h2>Hello from Docusaurus</h2>
|
||||
|
||||
Are you ready to create the documentation site for your open source project?
|
||||
|
||||
<h3>Headers</h3>
|
||||
|
||||
will show up on the table of contents on the upper right
|
||||
|
||||
So that your users will know what this page is all about without scrolling down or even without reading too much.
|
||||
|
||||
<h3>Only h2 and h3 will be in the TOC by default.</h3>
|
||||
|
||||
You can configure the TOC heading levels either per document or in the theme configuration.
|
||||
|
||||
The headers are well-spaced so that the hierarchy is clear.
|
||||
|
||||
- lists will help you
|
||||
- present the key points
|
||||
- that you want your users to remember
|
||||
- and you may nest them
|
||||
- multiple times
|
||||
|
||||
<h3 id="custom-id">Custom id headers</h3>
|
||||
|
||||
With <code>{#custom-id}</code> syntax you can set your own header id.
|
||||
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
All files prefixed with an underscore (`_`) under the `docs` directory are treated as "partial" pages and will be ignored by default.
|
||||
|
||||
Read more about [importing partial pages](../markdown-features/markdown-features-react.mdx#importing-markdown).
|
||||
|
||||
:::
|
||||
|
||||
## Doc tags {#doc-tags}
|
||||
|
||||
Optionally, you can add tags to your doc pages, which introduces another dimension of categorization in addition to the [docs sidebar](./sidebar/index.md). Tags are passed in the front matter as a list of labels:
|
||||
|
||||
```md "your-doc-page.md"
|
||||
---
|
||||
id: doc-with-tags
|
||||
title: A doc with tags
|
||||
tags:
|
||||
- Demo
|
||||
- Getting started
|
||||
---
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
Tags can also be declared with `tags: [Demo, Getting started]`.
|
||||
|
||||
Read more about all the possible [Yaml array syntaxes](https://www.w3schools.io/file/yaml-arrays/).
|
||||
|
||||
:::
|
|
@ -0,0 +1,163 @@
|
|||
---
|
||||
id: introduction
|
||||
title: Docs Introduction
|
||||
sidebar_label: Introduction
|
||||
slug: /docs-introduction
|
||||
---
|
||||
|
||||
The docs feature provides users with a way to organize Markdown files in a hierarchical format.
|
||||
|
||||
:::info
|
||||
|
||||
Check the [Docs Plugin API Reference documentation](./../../api/plugins/plugin-content-docs.md) for an exhaustive list of options.
|
||||
|
||||
:::
|
||||
|
||||
## Document ID {#document-id}
|
||||
|
||||
Every document has a unique `id`. By default, a document `id` is the name of the document (without the extension) relative to the root docs directory.
|
||||
|
||||
For example, `greeting.md` id is `greeting` and `guide/hello.md` id is `guide/hello`.
|
||||
|
||||
```bash
|
||||
website # Root directory of your site
|
||||
└── docs
|
||||
├── greeting.md
|
||||
└── guide
|
||||
└── hello.md
|
||||
```
|
||||
|
||||
However, the **last part** of the `id` can be defined by the user in the front matter. For example, if `guide/hello.md`'s content is defined as below, its final `id` is `guide/part1`.
|
||||
|
||||
```md
|
||||
---
|
||||
id: part1
|
||||
---
|
||||
|
||||
Lorem ipsum
|
||||
```
|
||||
|
||||
If you want more control over the last part of the document URL, it is possible to add a `slug` (defaults to the `id`).
|
||||
|
||||
```md
|
||||
---
|
||||
id: part1
|
||||
slug: part1.html
|
||||
---
|
||||
|
||||
Lorem ipsum
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
It is possible to use:
|
||||
|
||||
- absolute slugs: `slug: /mySlug`, `slug: /`...
|
||||
- relative slugs: `slug: mySlug`, `slug: ./../mySlug`...
|
||||
|
||||
:::
|
||||
|
||||
## Home page docs {#home-page-docs}
|
||||
|
||||
If you want a document to be available at the root, and have a path like `https://docusaurus.io/docs/`, you can use the slug front matter:
|
||||
|
||||
```md
|
||||
---
|
||||
id: my-home-doc
|
||||
slug: /
|
||||
---
|
||||
|
||||
Lorem ipsum
|
||||
```
|
||||
|
||||
## Docs-only mode {#docs-only-mode}
|
||||
|
||||
A freshly initialized Docusaurus site has the following structure:
|
||||
|
||||
```
|
||||
example.com/ -> generated from `src/pages/index.js`
|
||||
|
||||
example.com/docs/intro -> generated from `docs/intro.md`
|
||||
example.com/docs/tutorial-basics/... -> generated from `docs/tutorial-basics/...`
|
||||
...
|
||||
|
||||
example.com/blog/2021/08/26/welcome -> generated from `blog/2021-08-26-welcome/index.md`
|
||||
example.com/blog/2021/08/01/mdx-blog-post -> generated from `blog/2021-08-01-mdx-blog-post.mdx`
|
||||
...
|
||||
```
|
||||
|
||||
All docs will be served under the subroute `docs/`. But what if **your site only has docs**, or you want to prioritize your docs by putting them at the root?
|
||||
|
||||
Assume that you have the following in your configuration:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
presets: [
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
/* docs plugin options */
|
||||
},
|
||||
blog: {
|
||||
/* blog plugin options */
|
||||
},
|
||||
// ...
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
To enter docs-only mode, change it to like this:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
// ...
|
||||
presets: [
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-next-line
|
||||
routeBasePath: '/', // Serve the docs at the site's root
|
||||
/* other docs plugin options */
|
||||
},
|
||||
// highlight-next-line
|
||||
blog: false, // Optional: disable the blog plugin
|
||||
// ...
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Note that you **don't necessarily have to give up on using the blog** or other plugins; all that `routeBasePath: '/'` does is that instead of serving the docs through `https://example.com/docs/some-doc`, they are now at the site root: `https://example.com/some-doc`. The blog, if enabled, can still be accessed through the `blog/` subroute.
|
||||
|
||||
Don't forget to put some page at the root (`https://example.com/`) through adding the front matter:
|
||||
|
||||
```md title="docs/intro.md"
|
||||
---
|
||||
# highlight-next-line
|
||||
slug: /
|
||||
---
|
||||
|
||||
This page will be the home page when users visit https://example.com/.
|
||||
```
|
||||
|
||||
:::caution
|
||||
|
||||
If you added `slug: /` to a doc to make it the homepage, you should delete the existing homepage at `./src/pages/index.js`, or else there will be two files mapping to the same route!
|
||||
|
||||
:::
|
||||
|
||||
Now, the site's structure will be like the following:
|
||||
|
||||
```
|
||||
example.com/ -> generated from `docs/intro.md`
|
||||
example.com/tutorial-basics/... -> generated from `docs/tutorial-basics/...`
|
||||
...
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
There's also a "blog-only mode" for those who only want to use the blog feature of Docusaurus 2. You can use the same method detailed above. Follow the setup instructions on [Blog-only mode](../../blog.mdx#blog-only-mode).
|
||||
|
||||
:::
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
id: markdown-features
|
||||
title: Docs Markdown Features
|
||||
description: Docusaurus Markdown features that are specific to the docs plugin
|
||||
slug: /docs-markdown-features
|
||||
---
|
||||
|
||||
Docs can use any [Markdown feature](../markdown-features/markdown-features-intro.mdx) and have a few additional docs-specific Markdown features.
|
||||
|
||||
## Markdown front matter {#markdown-front-matter}
|
||||
|
||||
Markdown docs have their own [Markdown front matter API](../../api/plugins/plugin-content-docs.md#markdown-front-matter).
|
||||
|
||||
## Referencing other documents {#referencing-other-documents}
|
||||
|
||||
If you want to reference another document file, you could use the relative path of the document you want to link to.
|
||||
|
||||
Docusaurus will convert the file path to be the final document url path (and remove the `.md` extension).
|
||||
|
||||
For example, if you are in `folder/doc1.md` and you want to reference `folder/doc2.md`, `folder/subfolder/doc3.md` and `otherFolder/doc4.md`:
|
||||
|
||||
```md
|
||||
I am referencing a [document](doc2.md).
|
||||
|
||||
Reference to another [document in a subfolder](subfolder/doc3.md).
|
||||
|
||||
[Relative document](../otherFolder/doc4.md) referencing works as well.
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
Using relative _file_ paths (with `.md` extensions) instead of relative _URL_ links provides the following benefits:
|
||||
|
||||
- links will keep working on the GitHub interface
|
||||
- you can customize the document slugs without having to update all the links
|
||||
- a versioned doc will link to another doc of the exact same version
|
||||
- relative links are very likely to break if you update the [`trailingSlash` config](../../api/docusaurus.config.js.md#trailing-slash)
|
||||
|
||||
:::
|
|
@ -0,0 +1,212 @@
|
|||
---
|
||||
id: multi-instance
|
||||
title: Docs Multi-instance
|
||||
description: Use multiple docs plugin instances on a single Docusaurus site.
|
||||
slug: /docs-multi-instance
|
||||
---
|
||||
|
||||
The `@docusaurus/plugin-content-docs` plugin can support [multi-instance](../../using-plugins.md#multi-instance-plugins-and-plugin-ids).
|
||||
|
||||
:::note
|
||||
|
||||
This feature is only useful for [versioned documentation](./versioning.md). It is recommended to be familiar with docs versioning before reading this page. If you just want [multiple sidebars](./sidebar/multiple-sidebars.md), you can do so within one plugin.
|
||||
|
||||
:::
|
||||
|
||||
## Use-cases {#use-cases}
|
||||
|
||||
Sometimes you want a Docusaurus site to host 2 distinct sets of documentation (or more).
|
||||
|
||||
These documentations may even have different versioning/release lifecycles.
|
||||
|
||||
### Mobile SDKs documentation {#mobile-sdks-documentation}
|
||||
|
||||
If you build a cross-platform mobile SDK, you may have 2 documentations:
|
||||
|
||||
- Android SDK documentation (`v1.0`, `v1.1`)
|
||||
- iOS SDK documentation (`v1.0`, `v2.0`)
|
||||
|
||||
In this case, you can use a distinct docs plugin instance per mobile SDK documentation.
|
||||
|
||||
:::caution
|
||||
|
||||
If each documentation instance is very large, you should rather create 2 distinct Docusaurus sites.
|
||||
|
||||
If someone edits the iOS documentation, is it really useful to rebuild everything, including the whole Android documentation that did not change?
|
||||
|
||||
:::
|
||||
|
||||
### Versioned and unversioned doc {#versioned-and-unversioned-doc}
|
||||
|
||||
Sometimes, you want some documents to be versioned, while other documents are more "global", and it feels useless to version them.
|
||||
|
||||
We use this pattern on the Docusaurus website itself:
|
||||
|
||||
- The [/docs/\*](/docs) section is versioned
|
||||
- The [/community/\*](/community/support) section is unversioned
|
||||
|
||||
## Setup {#setup}
|
||||
|
||||
Suppose you have 2 documentations:
|
||||
|
||||
- Product: some versioned doc about your product
|
||||
- Community: some unversioned doc about the community around your product
|
||||
|
||||
In this case, you should use the same plugin twice in your site configuration.
|
||||
|
||||
:::caution
|
||||
|
||||
`@docusaurus/preset-classic` already includes a docs plugin instance for you!
|
||||
|
||||
:::
|
||||
|
||||
When using the preset:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-start
|
||||
// id: 'product', // omitted => default instance
|
||||
// highlight-end
|
||||
path: 'product',
|
||||
routeBasePath: 'product',
|
||||
sidebarPath: require.resolve('./sidebarsProduct.js'),
|
||||
// ... other options
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
// highlight-start
|
||||
id: 'community',
|
||||
// highlight-end
|
||||
path: 'community',
|
||||
routeBasePath: 'community',
|
||||
sidebarPath: require.resolve('./sidebarsCommunity.js'),
|
||||
// ... other options
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
When not using the preset:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
// highlight-start
|
||||
// id: 'product', // omitted => default instance
|
||||
// highlight-end
|
||||
path: 'product',
|
||||
routeBasePath: 'product',
|
||||
sidebarPath: require.resolve('./sidebarsProduct.js'),
|
||||
// ... other options
|
||||
},
|
||||
],
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
// highlight-start
|
||||
id: 'community',
|
||||
// highlight-end
|
||||
path: 'community',
|
||||
routeBasePath: 'community',
|
||||
sidebarPath: require.resolve('./sidebarsCommunity.js'),
|
||||
// ... other options
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Don't forget to assign a unique `id` attribute to plugin instances.
|
||||
|
||||
:::note
|
||||
|
||||
We consider that the `product` instance is the most important one, and make it the "default" instance by not assigning any id.
|
||||
|
||||
:::
|
||||
|
||||
## Versioned paths {#versioned-paths}
|
||||
|
||||
Each plugin instance will store versioned docs in a distinct folder.
|
||||
|
||||
The default plugin instance will use these paths:
|
||||
|
||||
- `website/versions.json`
|
||||
- `website/versioned_docs`
|
||||
- `website/versioned_sidebars`
|
||||
|
||||
The other plugin instances (with an `id` attribute) will use these paths:
|
||||
|
||||
- `website/[pluginId]_versions.json`
|
||||
- `website/[pluginId]_versioned_docs`
|
||||
- `website/[pluginId]_versioned_sidebars`
|
||||
|
||||
:::tip
|
||||
|
||||
You can omit the `id` attribute (defaults to `default`) for one of the docs plugin instances.
|
||||
|
||||
The instance paths will be simpler, and retro-compatible with a single-instance setup.
|
||||
|
||||
:::
|
||||
|
||||
## Tagging new versions {#tagging-new-versions}
|
||||
|
||||
Each plugin instance will have its own cli command to tag a new version. They will be displayed if you run:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run docusaurus -- --help
|
||||
```
|
||||
|
||||
To version the product/default docs plugin instance:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run docusaurus docs:version 1.0.0
|
||||
```
|
||||
|
||||
To version the non-default/community docs plugin instance:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run docusaurus docs:version:community 1.0.0
|
||||
```
|
||||
|
||||
## Docs navbar items {#docs-navbar-items}
|
||||
|
||||
Each docs-related [theme navbar items](../../api/themes/theme-configuration.md#navbar) take an optional `docsPluginId` attribute.
|
||||
|
||||
For example, if you want to have one version dropdown for each mobile SDK (iOS and Android), you could do:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
items: [
|
||||
{
|
||||
type: 'docsVersionDropdown',
|
||||
// highlight-start
|
||||
docsPluginId: 'ios',
|
||||
// highlight-end
|
||||
},
|
||||
{
|
||||
type: 'docsVersionDropdown',
|
||||
// highlight-start
|
||||
docsPluginId: 'android',
|
||||
// highlight-end
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
|
@ -0,0 +1,487 @@
|
|||
---
|
||||
slug: /sidebar/autogenerated
|
||||
---
|
||||
|
||||
# Autogenerated
|
||||
|
||||
```mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
```
|
||||
|
||||
Docusaurus can **create a sidebar automatically** from your **filesystem structure**: each folder creates a sidebar category, and each file creates a doc link.
|
||||
|
||||
```ts
|
||||
type SidebarItemAutogenerated = {
|
||||
type: 'autogenerated';
|
||||
dirName: string; // Source folder to generate the sidebar slice from (relative to docs)
|
||||
};
|
||||
```
|
||||
|
||||
Docusaurus can generate a full sidebar from your docs folder:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
myAutogeneratedSidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: '.', // '.' means the current docs folder
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
An `autogenerated` item is converted by Docusaurus to a **sidebar slice** (also discussed in [category shorthands](items.md#category-shorthand)): a list of items of type `doc` or `category`, so you can splice **multiple `autogenerated` items** from multiple directories, interleaving them with regular sidebar items, in one sidebar level.
|
||||
|
||||
<details>
|
||||
<summary>A real-world example</summary>
|
||||
Consider this file structure:
|
||||
|
||||
```bash
|
||||
docs
|
||||
├── api
|
||||
│ ├── product1-api
|
||||
│ │ └── api.md
|
||||
│ └── product2-api
|
||||
│ ├── basic-api.md
|
||||
│ └── pro-api.md
|
||||
├── intro.md
|
||||
└── tutorials
|
||||
├── advanced
|
||||
│ ├── advanced1.md
|
||||
│ ├── advanced2.md
|
||||
│ └── read-more
|
||||
│ ├── resource1.md
|
||||
│ └── resource2.md
|
||||
├── easy
|
||||
│ ├── easy1.md
|
||||
│ └── easy2.md
|
||||
├── tutorial-end.md
|
||||
├── tutorial-intro.md
|
||||
└── tutorial-medium.md
|
||||
```
|
||||
|
||||
And assume every doc's ID is just its file name. If you define an autogenerated sidebar like this:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
'intro',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorials',
|
||||
items: [
|
||||
'tutorial-intro',
|
||||
// highlight-start
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'tutorials/easy', // Generate sidebar slice from docs/tutorials/easy
|
||||
},
|
||||
// highlight-end
|
||||
'tutorial-medium',
|
||||
// highlight-start
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'tutorials/advanced', // Generate sidebar slice from docs/tutorials/hard
|
||||
},
|
||||
// highlight-end
|
||||
'tutorial-end',
|
||||
],
|
||||
},
|
||||
// highlight-start
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'api', // Generate sidebar slice from docs/api
|
||||
},
|
||||
// highlight-end
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Community',
|
||||
items: ['team', 'chat'],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
It would be resolved as:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
'intro',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorials',
|
||||
items: [
|
||||
'tutorial-intro',
|
||||
// highlight-start
|
||||
// Two files in docs/tutorials/easy
|
||||
'easy1',
|
||||
'easy2',
|
||||
// highlight-end
|
||||
'tutorial-medium',
|
||||
// highlight-start
|
||||
// Two files and a folder in docs/tutorials/hard
|
||||
'advanced1',
|
||||
'advanced2',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'read-more',
|
||||
items: ['resource1', 'resource2'],
|
||||
},
|
||||
// highlight-end
|
||||
'tutorial-end',
|
||||
],
|
||||
},
|
||||
// highlight-start
|
||||
// Two folders in docs/api
|
||||
{
|
||||
type: 'category',
|
||||
label: 'product1-api',
|
||||
items: ['api'],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'product2-api',
|
||||
items: ['basic-api', 'pro-api'],
|
||||
},
|
||||
// highlight-end
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Community',
|
||||
items: ['team', 'chat'],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Note how the autogenerate source directories themselves don't become categories: only the items they contain do. This is what we mean by "sidebar slice".
|
||||
|
||||
</details>
|
||||
|
||||
## Category index convention {#category-index-convention}
|
||||
|
||||
Docusaurus can automatically link a category to its index document.
|
||||
|
||||
A category index document is a document following one of those filename conventions:
|
||||
|
||||
- Named as `index` (case-insensitive): `docs/Guides/index.md`
|
||||
- Named as `README` (case-insensitive): `docs/Guides/README.mdx`
|
||||
- Same name as parent folder: `docs/Guides/Guides.md`
|
||||
|
||||
This is equivalent to using a category with a [doc link](items.md#category-doc-link):
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
link: {type: 'doc', id: 'Guides/index'},
|
||||
items: [],
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
Naming your introductory document `README.md` makes it show up when browsing the folder using the GitHub interface, while using `index.md` makes the behavior more in line with how HTML files are served.
|
||||
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
If a folder only has one index page, it will be turned into a link instead of a category. This is useful for **asset collocation**:
|
||||
|
||||
```
|
||||
some-doc
|
||||
├── index.md
|
||||
├── img1.png
|
||||
└── img2.png
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Customizing category index matching</summary>
|
||||
|
||||
It is possible to opt out any of the category index conventions, or define even more conventions. You can inject your own `isCategoryIndex` matcher through the [`sidebarItemsGenerator`](#customize-the-sidebar-items-generator) callback. For example, you can also pick `intro` as another file name eligible for automatically becoming the category index.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
async sidebarItemsGenerator({
|
||||
...args,
|
||||
isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below
|
||||
defaultSidebarItemsGenerator,
|
||||
}) {
|
||||
return defaultSidebarItemsGenerator({
|
||||
...args,
|
||||
// highlight-start
|
||||
isCategoryIndex(doc) {
|
||||
return (
|
||||
// Also pick intro.md in addition to the default ones
|
||||
doc.fileName.toLowerCase() === 'intro' ||
|
||||
defaultCategoryIndexMatcher(doc)
|
||||
);
|
||||
},
|
||||
// highlight-end
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Or choose to not have any category index convention.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
async sidebarItemsGenerator({
|
||||
...args,
|
||||
isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below
|
||||
defaultSidebarItemsGenerator,
|
||||
}) {
|
||||
return defaultSidebarItemsGenerator({
|
||||
...args,
|
||||
// highlight-start
|
||||
isCategoryIndex() {
|
||||
// No doc will be automatically picked as category index
|
||||
return false;
|
||||
},
|
||||
// highlight-end
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
The `isCategoryIndex` matcher will be provided with three fields:
|
||||
|
||||
- `fileName`, the file's name without extension and with casing preserved
|
||||
- `directories`, the list of directory names _from the lowest level to the highest level_, relative to the docs root directory
|
||||
- `extension`, the file's extension, with a leading dot.
|
||||
|
||||
For example, for a doc file at `guides/sidebar/autogenerated.md`, the props the matcher receives are
|
||||
|
||||
```js
|
||||
const props = {
|
||||
fileName: 'autogenerated',
|
||||
directories: ['sidebar', 'guides'],
|
||||
extension: '.md',
|
||||
};
|
||||
```
|
||||
|
||||
The default implementation is:
|
||||
|
||||
```js
|
||||
function isCategoryIndex({fileName, directories}) {
|
||||
const eligibleDocIndexNames = [
|
||||
'index',
|
||||
'readme',
|
||||
directories[0].toLowerCase(),
|
||||
];
|
||||
return eligibleDocIndexNames.includes(fileName.toLowerCase());
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Autogenerated sidebar metadata {#autogenerated-sidebar-metadata}
|
||||
|
||||
For handwritten sidebar definitions, you would provide metadata to sidebar items through `sidebars.js`; for autogenerated, Docusaurus would read them from the item's respective file. In addition, you may want to adjust the relative position of each item because, by default, items within a sidebar slice will be generated in **alphabetical order** (using file and folder names).
|
||||
|
||||
**For docs**: use additional front matter. The `label`, `className`, and `customProps` attributes are declared in front matter as `sidebar_label`, `sidebar_class_name`, and `sidebar_custom_props`, respectively. Position can be specified in the same way, via `sidebar_position` front matter.
|
||||
|
||||
```md title="docs/tutorials/tutorial-easy.md"
|
||||
---
|
||||
# highlight-start
|
||||
sidebar_position: 2
|
||||
sidebar_label: Easy
|
||||
sidebar_class_name: green
|
||||
# highlight-end
|
||||
---
|
||||
|
||||
# Easy Tutorial
|
||||
|
||||
This is the easy tutorial!
|
||||
```
|
||||
|
||||
**For categories**: add a `_category_.json` or `_category_.yml` file in the respective folder. You can specify any category metadata and also the `position` metadata.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="JSON">
|
||||
|
||||
```json title="docs/tutorials/_category_.json"
|
||||
{
|
||||
"position": 2.5,
|
||||
"label": "Tutorial",
|
||||
"collapsible": true,
|
||||
"collapsed": false,
|
||||
"className": "red",
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Tutorial overview"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="YAML">
|
||||
|
||||
```yml title="docs/tutorials/_category_.yml"
|
||||
position: 2.5 # float position is supported
|
||||
label: 'Tutorial'
|
||||
collapsible: true # make the category collapsible
|
||||
collapsed: false # keep the category open by default
|
||||
className: red
|
||||
link:
|
||||
type: generated-index
|
||||
title: Tutorial overview
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::info
|
||||
|
||||
If the `link` is explicitly specified, Docusaurus will not apply any [default conventions](items.md#category-index-convention).
|
||||
|
||||
The doc links can be specified relatively, e.g. if the category is generated with the `guides` directory, `"link": {"type": "doc", "id": "intro"}` will be resolved to the ID `guides/intro`, only falling back to `intro` if a doc with the former ID doesn't exist.
|
||||
|
||||
You can also use `link: null` to opt out of default conventions and not generate any category index page.
|
||||
|
||||
:::
|
||||
|
||||
:::info
|
||||
|
||||
The position metadata is only used **within a sidebar slice**: Docusaurus does not re-order other items of your sidebar.
|
||||
|
||||
:::
|
||||
|
||||
## Using number prefixes {#using-number-prefixes}
|
||||
|
||||
A simple way to order an autogenerated sidebar is to prefix docs and folders by number prefixes, which also makes them appear in the file system in the same order when sorted by file name:
|
||||
|
||||
```bash
|
||||
docs
|
||||
├── 01-Intro.md
|
||||
├── 02-Tutorial Easy
|
||||
│ ├── 01-First Part.md
|
||||
│ ├── 02-Second Part.md
|
||||
│ └── 03-End.md
|
||||
├── 03-Tutorial Hard
|
||||
│ ├── 01-First Part.md
|
||||
│ ├── 02-Second Part.md
|
||||
│ ├── 03-Third Part.md
|
||||
│ └── 04-End.md
|
||||
└── 04-End.md
|
||||
```
|
||||
|
||||
To make it **easier to adopt**, Docusaurus supports **multiple number prefix patterns**.
|
||||
|
||||
By default, Docusaurus will **remove the number prefix** from the doc id, title, label, and URL paths.
|
||||
|
||||
:::caution
|
||||
|
||||
**Prefer using [additional metadata](#autogenerated-sidebar-metadata)**.
|
||||
|
||||
Updating a number prefix can be annoying, as it can require **updating multiple existing markdown links**:
|
||||
|
||||
```diff title="docs/02-Tutorial Easy/01-First Part.md"
|
||||
- Check the [Tutorial End](../04-End.md);
|
||||
+ Check the [Tutorial End](../05-End.md);
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Customize the sidebar items generator {#customize-the-sidebar-items-generator}
|
||||
|
||||
You can provide a custom `sidebarItemsGenerator` function in the docs plugin (or preset) config:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
// highlight-start
|
||||
async sidebarItemsGenerator({
|
||||
defaultSidebarItemsGenerator,
|
||||
numberPrefixParser,
|
||||
item,
|
||||
version,
|
||||
docs,
|
||||
categoriesMetadata,
|
||||
isCategoryIndex,
|
||||
}) {
|
||||
// Example: return an hardcoded list of static sidebar items
|
||||
return [
|
||||
{type: 'doc', id: 'doc1'},
|
||||
{type: 'doc', id: 'doc2'},
|
||||
];
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
**Re-use and enhance the default generator** instead of writing a generator from scratch: [the default generator we provide](https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts) is 250 lines long.
|
||||
|
||||
**Add, update, filter, re-order** the sidebar items according to your use case:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
// highlight-start
|
||||
// Reverse the sidebar items ordering (including nested category items)
|
||||
function reverseSidebarItems(items) {
|
||||
// Reverse items in categories
|
||||
const result = items.map((item) => {
|
||||
if (item.type === 'category') {
|
||||
return {...item, items: reverseSidebarItems(item.items)};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
// Reverse items at current level
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
// highlight-end
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
[
|
||||
'@docusaurus/plugin-content-docs',
|
||||
{
|
||||
// highlight-start
|
||||
async sidebarItemsGenerator({defaultSidebarItemsGenerator, ...args}) {
|
||||
const sidebarItems = await defaultSidebarItemsGenerator(args);
|
||||
return reverseSidebarItems(sidebarItems);
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
|
@ -0,0 +1,201 @@
|
|||
---
|
||||
slug: /sidebar
|
||||
---
|
||||
|
||||
# Sidebar
|
||||
|
||||
Creating a sidebar is useful to:
|
||||
|
||||
- Group multiple **related documents**
|
||||
- **Display a sidebar** on each of those documents
|
||||
- Provide **paginated navigation**, with next/previous button
|
||||
|
||||
To use sidebars on your Docusaurus site:
|
||||
|
||||
1. Define a file that exports a dictionary of [sidebar objects](#sidebar-object).
|
||||
2. Pass this object into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-next-line
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
This section serves as an overview of miscellaneous features of the doc sidebar. In the following sections, we will more systematically introduce the following concepts:
|
||||
|
||||
```mdx-code-block
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
```
|
||||
|
||||
## Default sidebar {#default-sidebar}
|
||||
|
||||
If the `sidebarPath` is unspecified, Docusaurus [automatically generates a sidebar](autogenerated.md) for you, by using the filesystem structure of the `docs` folder:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: '.', // generate sidebar from the docs folder (or versioned_docs/<version>)
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
You can also define your sidebars explicitly.
|
||||
|
||||
## Sidebar object {#sidebar-object}
|
||||
|
||||
A sidebar at its crux is a hierarchy of categories, doc links, and other hyperlinks.
|
||||
|
||||
```ts
|
||||
type Sidebar =
|
||||
// Normal syntax
|
||||
| SidebarItem[]
|
||||
// Shorthand syntax
|
||||
| {[categoryLabel: string]: SidebarItem[]};
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting Started',
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docusaurus',
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc2',
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc3',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Learn more',
|
||||
href: 'https://example.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
This is a sidebars file that exports one sidebar, called `mySidebar`. It has three top-level items: two categories and one external link. Within each category, there are a few doc links.
|
||||
|
||||
A sidebars file can contain [**multiple sidebar objects**](multiple-sidebars.md), identified by their object keys.
|
||||
|
||||
```ts
|
||||
type SidebarsFile = {
|
||||
[sidebarID: string]: Sidebar;
|
||||
};
|
||||
```
|
||||
|
||||
## Theme configuration {#theme-configuration}
|
||||
|
||||
### Hideable sidebar {#hideable-sidebar}
|
||||
|
||||
By enabling the `themeConfig.hideableSidebar` option, you can make the entire sidebar hideable, allowing users to better focus on the content. This is especially useful when content is consumed on medium-sized screens (e.g. tablets).
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
// highlight-start
|
||||
hideableSidebar: true,
|
||||
// highlight-end
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Auto-collapse sidebar categories {#auto-collapse-sidebar-categories}
|
||||
|
||||
The `themeConfig.autoCollapseSidebarCategories` option would collapse all sibling categories when expanding one category. This saves the user from having too many categories open and helps them focus on the selected section.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
// highlight-next-line
|
||||
autoCollapseSidebarCategories: true,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Passing custom props {#passing-custom-props}
|
||||
|
||||
To pass in custom props to a swizzled sidebar item, add the optional `customProps` object to any of the items:
|
||||
|
||||
```js
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc1',
|
||||
customProps: {
|
||||
/* props */
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Sidebar Breadcrumbs {#sidebar-breadcrumbs}
|
||||
|
||||
By default, breadcrumbs are rendered at the top, using the "sidebar path" of the current page.
|
||||
|
||||
This behavior can be disabled with plugin options:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-next-line
|
||||
breadcrumbs: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## Complex sidebars example {#complex-sidebars-example}
|
||||
|
||||
A real-world example from the Docusaurus site:
|
||||
|
||||
```mdx-code-block
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
<CodeBlock className="language-js" title="sidebars.js">
|
||||
{require('!!raw-loader!@site/sidebars.js')
|
||||
.default
|
||||
.split('\n')
|
||||
// remove comments
|
||||
.map((line) => !['//','/*','*'].some(commentPattern => line.trim().startsWith(commentPattern)) && line)
|
||||
.filter(Boolean)
|
||||
.join('\n')}
|
||||
</CodeBlock>
|
||||
```
|
|
@ -0,0 +1,591 @@
|
|||
---
|
||||
toc_max_heading_level: 4
|
||||
slug: /sidebar/items
|
||||
---
|
||||
|
||||
# Sidebar items
|
||||
|
||||
```mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
```
|
||||
|
||||
We have introduced three types of item types in the example in the previous section: `doc`, `category`, and `link`, whose usages are fairly intuitive. We will formally introduce their APIs. There's also a fourth type: `autogenerated`, which we will explain in detail later.
|
||||
|
||||
- **[Doc](#sidebar-item-doc)**: link to a doc page, associating it with the sidebar
|
||||
- **[Link](#sidebar-item-link)**: link to any internal or external page
|
||||
- **[Category](#sidebar-item-category)**: creates a dropdown of sidebar items
|
||||
- **[Autogenerated](autogenerated.md)**: generate a sidebar slice automatically
|
||||
- **[HTML](#sidebar-item-html)**: renders pure HTML in the item's position
|
||||
- **[\*Ref](multiple-sidebars.md#sidebar-item-ref)**: link to a doc page, without making the item take part in navigation generation
|
||||
|
||||
## Doc: link to a doc {#sidebar-item-doc}
|
||||
|
||||
Use the `doc` type to link to a doc page and assign that doc to a sidebar:
|
||||
|
||||
```ts
|
||||
type SidebarItemDoc =
|
||||
// Normal syntax
|
||||
| {
|
||||
type: 'doc';
|
||||
id: string;
|
||||
label: string; // Sidebar label text
|
||||
className?: string; // Class name for sidebar label
|
||||
customProps?: Record<string, unknown>; // Custom props
|
||||
}
|
||||
|
||||
// Shorthand syntax
|
||||
| string; // docId shortcut
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
// Normal syntax:
|
||||
// highlight-start
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'doc1', // document ID
|
||||
label: 'Getting started', // sidebar label
|
||||
},
|
||||
// highlight-end
|
||||
|
||||
// Shorthand syntax:
|
||||
// highlight-start
|
||||
'doc2', // document ID
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
If you use the doc shorthand or [autogenerated](#sidebar-item-autogenerated) sidebar, you would lose the ability to customize the sidebar label through item definition. You can, however, use the `sidebar_label` markdown front matter within that doc, which has higher precedence over the `label` key in the sidebar item. Similarly, you can use `sidebar_custom_props` to declare custom metadata for a doc page.
|
||||
|
||||
:::note
|
||||
|
||||
A `doc` item sets an [implicit sidebar association](#sidebar-association). Don't assign the same doc to multiple sidebars: change the type to `ref` instead.
|
||||
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
Sidebar custom props is a useful way to propagate arbitrary doc metadata to the client side, so you can get additional information when using any doc-related hook that fetches a doc object.
|
||||
|
||||
:::
|
||||
|
||||
## Link: link to any page {#sidebar-item-link}
|
||||
|
||||
Use the `link` type to link to any page (internal or external) that is not a doc.
|
||||
|
||||
```ts
|
||||
type SidebarItemLink = {
|
||||
type: 'link';
|
||||
label: string;
|
||||
href: string;
|
||||
className?: string;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
myLinksSidebar: [
|
||||
// highlight-start
|
||||
// External link
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Facebook', // The link label
|
||||
href: 'https://facebook.com', // The external URL
|
||||
},
|
||||
// highlight-end
|
||||
|
||||
// highlight-start
|
||||
// Internal link
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Home', // The link label
|
||||
href: '/', // The internal path
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## HTML: render custom markup {#sidebar-item-html}
|
||||
|
||||
Use the `html` type to render custom HTML within the item's `<li>` tag.
|
||||
|
||||
This can be useful for inserting custom items such as dividers, section titles, ads, and images.
|
||||
|
||||
```ts
|
||||
type SidebarItemHtml = {
|
||||
type: 'html';
|
||||
value: string;
|
||||
defaultStyle?: boolean; // Use default menu item styles
|
||||
className?: string;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
myHtmlSidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'html',
|
||||
value: '<img src="sponsor.png" alt="Sponsor" />', // The HTML to be rendered
|
||||
defaultStyle: true, // Use the default menu item styling
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
The menu item is already wrapped in an `<li>` tag, so if your custom item is simple, such as a title, just supply a string as the value and use the `className` property to style it:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
myHtmlSidebar: [
|
||||
{
|
||||
type: 'html',
|
||||
value: 'Core concepts',
|
||||
className: 'sidebar-title',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Category: create a hierarchy {#sidebar-item-category}
|
||||
|
||||
Use the `category` type to create a hierarchy of sidebar items.
|
||||
|
||||
```ts
|
||||
type SidebarItemCategory = {
|
||||
type: 'category';
|
||||
label: string; // Sidebar label text.
|
||||
items: SidebarItem[]; // Array of sidebar items.
|
||||
className?: string;
|
||||
|
||||
// Category options:
|
||||
collapsible: boolean; // Set the category to be collapsible
|
||||
collapsed: boolean; // Set the category to be initially collapsed or open by default
|
||||
link: SidebarItemCategoryLinkDoc | SidebarItemCategoryLinkGeneratedIndex;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
collapsible: true,
|
||||
collapsed: false,
|
||||
items: [
|
||||
'creating-pages',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docs',
|
||||
items: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
Use the [**shorthand syntax**](#category-shorthand) when you don't need customizations:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: {
|
||||
Guides: [
|
||||
'creating-pages',
|
||||
{
|
||||
Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Category links {#category-link}
|
||||
|
||||
With category links, clicking on a category can navigate you to another page.
|
||||
|
||||
:::tip
|
||||
|
||||
Use category links to introduce a category of documents.
|
||||
|
||||
:::
|
||||
|
||||
#### Doc link {#category-doc-link}
|
||||
|
||||
A category can link to an existing document.
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
// highlight-start
|
||||
link: {type: 'doc', id: 'introduction'},
|
||||
// highlight-end
|
||||
items: ['pages', 'docs', 'blog', 'search'],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
See it in action on the [i18n introduction page](../../../i18n/i18n-introduction.md).
|
||||
|
||||
#### Generated index page {#generated-index-page}
|
||||
|
||||
You can auto-generate an index page that displays all the direct children of this category. The `slug` allows you to customize the generated page's route, which defaults to `/category/[categoryName]`.
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
// highlight-start
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Docusaurus Guides',
|
||||
description: 'Learn about the most important Docusaurus concepts!',
|
||||
slug: '/category/docusaurus-guides',
|
||||
keywords: ['guides'],
|
||||
image: '/img/docusaurus.png',
|
||||
},
|
||||
// highlight-end
|
||||
items: ['pages', 'docs', 'blog', 'search'],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
See it in action on the [Docusaurus Guides page](/docs/category/guides).
|
||||
|
||||
:::tip
|
||||
|
||||
Use `generated-index` links as a quick way to get an introductory document.
|
||||
|
||||
:::
|
||||
|
||||
#### Embedding generated index in doc page {#embedding-generated-index-in-doc-page}
|
||||
|
||||
You can embed the generated cards list in a normal doc page as well, as long as the doc is used as a category index page. To do so, you need to use the `DocCardList` component, paired with the `useCurrentSidebarCategory` hook.
|
||||
|
||||
```jsx title="a-category-index-page.md"
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
In this section, we will introduce the following concepts:
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||
```
|
||||
|
||||
See this in action on the [sidebar guides page](index.md).
|
||||
|
||||
### Collapsible categories {#collapsible-categories}
|
||||
|
||||
We support the option to expand/collapse categories. Categories are collapsible by default, but you can disable collapsing with `collapsible: false`.
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
items: [
|
||||
'creating-pages',
|
||||
{
|
||||
type: 'category',
|
||||
// highlight-next-line
|
||||
collapsible: false,
|
||||
label: 'Docs',
|
||||
items: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
To make all categories non-collapsible by default, set the `sidebarCollapsible` option in `plugin-content-docs` to `false`:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-next-line
|
||||
sidebarCollapsible: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
The option in `sidebars.js` takes precedence over plugin configuration, so it is possible to make certain categories collapsible when `sidebarCollapsible` is set to `false` globally.
|
||||
|
||||
:::
|
||||
|
||||
### Expanded categories by default {#expanded-categories-by-default}
|
||||
|
||||
Collapsible categories are collapsed by default. If you want them to be expanded on the first render, you can set `collapsed` to `false`:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
docs: {
|
||||
Guides: [
|
||||
'creating-pages',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docs',
|
||||
// highlight-next-line
|
||||
collapsed: false,
|
||||
items: ['markdown-features', 'sidebar', 'versioning'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Similar to `collapsible`, you can also set the global configuration `options.sidebarCollapsed` to `false`. Individual `collapsed` options in `sidebars.js` will still take precedence over this configuration.
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
// highlight-next-line
|
||||
sidebarCollapsed: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::caution
|
||||
|
||||
When a category has `collapsed: true` but `collapsible: false` (either through `sidebars.js` or through plugin configuration), the latter takes precedence and the category is still rendered as expanded.
|
||||
|
||||
:::
|
||||
|
||||
## Using shorthands {#using-shorthands}
|
||||
|
||||
You can express typical sidebar items without much customization more concisely with **shorthand syntaxes**. There are two parts to this: [**doc shorthand**](#doc-shorthand) and [**category shorthand**](#category-shorthand).
|
||||
|
||||
### Doc shorthand {#doc-shorthand}
|
||||
|
||||
An item with type `doc` can be simply a string representing its ID:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Longhand">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'myDoc',
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="Shorthand">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: [
|
||||
// highlight-start
|
||||
'myDoc',
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
So it's possible to simplify the example above to:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting Started',
|
||||
items: [
|
||||
// highlight-next-line
|
||||
'doc1',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Docusaurus',
|
||||
items: [
|
||||
// highlight-start
|
||||
'doc2',
|
||||
'doc3',
|
||||
// highlight-end
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Learn more',
|
||||
href: 'https://example.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Category shorthand {#category-shorthand}
|
||||
|
||||
A category item can be represented by an object whose key is its label, and the value is an array of subitems.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Longhand">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting started',
|
||||
items: ['doc1', 'doc2'],
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="Shorthand">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
'Getting started': ['doc1', 'doc2'],
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This permits us to simplify that example to:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
'Getting started': ['doc1'],
|
||||
},
|
||||
{
|
||||
Docusaurus: ['doc2', 'doc3'],
|
||||
},
|
||||
// highlight-end
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Learn more',
|
||||
href: 'https://example.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Each shorthand object after this transformation will contain exactly one entry. Now consider the further simplified example below:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
mySidebar: [
|
||||
// highlight-start
|
||||
{
|
||||
'Getting started': ['doc1'],
|
||||
Docusaurus: ['doc2', 'doc3'],
|
||||
},
|
||||
// highlight-end
|
||||
{
|
||||
type: 'link',
|
||||
label: 'Learn more',
|
||||
href: 'https://example.com',
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
Note how the two consecutive category shorthands are compressed into one object with two entries. This syntax generates a **sidebar slice**: you shouldn't see that object as one bulk item—this object is unwrapped, with each entry becoming a separate item, and they spliced together with the rest of the items (in this case, the "Learn more" link) to form the final sidebar level. Sidebar slices are also important when discussing [autogenerated sidebars](autogenerated.md).
|
||||
|
||||
Wherever you have an array of items that is reduced to one category shorthand, you can omit that enclosing array as well.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Before">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: [
|
||||
{
|
||||
'Getting started': ['doc1'],
|
||||
Docusaurus: [
|
||||
{
|
||||
'Basic guides': ['doc2', 'doc3'],
|
||||
'Advanced guides': ['doc4', 'doc5'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="After">
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
sidebar: {
|
||||
'Getting started': ['doc1'],
|
||||
Docusaurus: {
|
||||
'Basic guides': ['doc2', 'doc3'],
|
||||
'Advanced guides': ['doc4', 'doc5'],
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
|
@ -0,0 +1,142 @@
|
|||
---
|
||||
slug: /sidebar/multiple-sidebars
|
||||
---
|
||||
|
||||
# Using multiple sidebars
|
||||
|
||||
You can create a sidebar for each **set of Markdown files** that you want to **group together**.
|
||||
|
||||
:::tip
|
||||
|
||||
The Docusaurus site is a good example of using multiple sidebars:
|
||||
|
||||
- [Docs](../../../introduction.md)
|
||||
- [API](../../../cli.md)
|
||||
|
||||
:::
|
||||
|
||||
Consider this example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
tutorialSidebar: {
|
||||
'Category A': ['doc1', 'doc2'],
|
||||
},
|
||||
apiSidebar: ['doc3', 'doc4'],
|
||||
};
|
||||
```
|
||||
|
||||
When browsing `doc1` or `doc2`, the `tutorialSidebar` will be displayed; when browsing `doc3` or `doc4`, the `apiSidebar` will be displayed.
|
||||
|
||||
## Understanding sidebar association {#sidebar-association}
|
||||
|
||||
Following the example above, if a `commonDoc` is included in both sidebars:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
tutorialSidebar: {
|
||||
'Category A': ['doc1', 'doc2', 'commonDoc'],
|
||||
},
|
||||
apiSidebar: ['doc3', 'doc4', 'commonDoc'],
|
||||
};
|
||||
```
|
||||
|
||||
How does Docusaurus know which sidebar to display when browsing `commonDoc`? Answer: it doesn't, and we don't guarantee which sidebar it will pick.
|
||||
|
||||
When you add doc Y to sidebar X, it creates a two-way binding: sidebar X contains a link to doc Y, and when browsing doc Y, sidebar X will be displayed. But sometimes, we want to break either implicit binding:
|
||||
|
||||
1. _How do I generate a link to doc Y in sidebar X without making sidebar X displayed on Y?_ For example, when I include doc Y in multiple sidebars as in the example above, and I want to explicitly tell Docusaurus to display one sidebar?
|
||||
2. _How do I make sidebar X displayed when browsing doc Y, but sidebar X shouldn't contain the link to Y?_ For example, when Y is a "doc home page" and the sidebar is purely used for navigation?
|
||||
|
||||
Front matter option `displayed_sidebar` will forcibly set the sidebar association. For the same example, you can still use doc shorthands without any special configuration:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
tutorialSidebar: {
|
||||
'Category A': ['doc1', 'doc2'],
|
||||
},
|
||||
apiSidebar: ['doc3', 'doc4'],
|
||||
};
|
||||
```
|
||||
|
||||
And then add a front matter:
|
||||
|
||||
```md title="commonDoc.md"
|
||||
---
|
||||
displayed_sidebar: apiSidebar
|
||||
---
|
||||
```
|
||||
|
||||
Which explicitly tells Docusaurus to display `apiSidebar` when browsing `commonDoc`. Using the same method, you can make sidebar X which doesn't contain doc Y appear on doc Y:
|
||||
|
||||
```md title="home.md"
|
||||
---
|
||||
displayed_sidebar: tutorialSidebar
|
||||
---
|
||||
```
|
||||
|
||||
Even when `tutorialSidebar` doesn't contain a link to `home`, it will still be displayed when viewing `home`.
|
||||
|
||||
If you set `displayed_sidebar: null`, no sidebar will be displayed whatsoever on this page, and subsequently, no pagination either.
|
||||
|
||||
## Generating pagination {#generating-pagination}
|
||||
|
||||
Docusaurus uses the sidebar to generate the "next" and "previous" pagination links at the bottom of each doc page. It strictly uses the sidebar that is displayed: if no sidebar is associated, it doesn't generate pagination either. However, the docs linked as "next" and "previous" are not guaranteed to display the same sidebar: they are included in this sidebar, but in their front matter, they may have a different `displayed_sidebar`.
|
||||
|
||||
If a sidebar is displayed by setting `displayed_sidebar` front matter, and this sidebar doesn't contain the doc itself, no pagination is displayed.
|
||||
|
||||
You can customize pagination with front matter `pagination_next` and `pagination_prev`. Consider this sidebar:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
tutorial: [
|
||||
'introduction',
|
||||
{
|
||||
installation: ['windows', 'linux', 'macos'],
|
||||
},
|
||||
'getting-started',
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
The pagination next link on "windows" points to "linux", but that doesn't make sense: you would want readers to proceed to "getting started" after installation. In this case, you can set the pagination manually:
|
||||
|
||||
```md title="windows.md"
|
||||
---
|
||||
# highlight-next-line
|
||||
pagination_next: getting-started
|
||||
---
|
||||
|
||||
# Installation on Windows
|
||||
```
|
||||
|
||||
You can also disable displaying a pagination link with `pagination_next: null` or `pagination_prev: null`.
|
||||
|
||||
The pagination label by default is the sidebar label. You can use the front matter `pagination_label` to customize how this doc appears in the pagination.
|
||||
|
||||
## The `ref` item {#sidebar-item-ref}
|
||||
|
||||
The `ref` type is identical to the [`doc` type](#sidebar-item-doc) in every way, except that it doesn't participate in generating navigation metadata. It only registers itself as a link. When [generating pagination](#generating-pagination) and [displaying sidebar](#sidebar-association), `ref` items are completely ignored.
|
||||
|
||||
Consider this example:
|
||||
|
||||
```js title="sidebars.js"
|
||||
module.exports = {
|
||||
tutorialSidebar: {
|
||||
'Category A': [
|
||||
'doc1',
|
||||
'doc2',
|
||||
// highlight-next-line
|
||||
{type: 'ref', id: 'commonDoc'},
|
||||
'doc5',
|
||||
],
|
||||
},
|
||||
apiSidebar: ['doc3', 'doc4', 'commonDoc'],
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
You can think of the `ref` type as the equivalent to doing the following:
|
||||
|
||||
- Setting `displayed_sidebar: tutorialSidebar` for `commonDoc` (`ref` is ignored in sidebar association)
|
||||
- Setting `pagination_next: doc5` for `doc2` and setting `pagination_prev: doc2` for `doc5` (`ref` is ignored in pagination generation)
|
|
@ -0,0 +1,280 @@
|
|||
---
|
||||
id: versioning
|
||||
title: Versioning
|
||||
slug: /versioning
|
||||
---
|
||||
|
||||
```mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
```
|
||||
|
||||
You can use the version script to create a new documentation version based on the latest content in the `docs` directory. That specific set of documentation will then be preserved and accessible even as the documentation in the `docs` directory changes moving forward.
|
||||
|
||||
:::caution
|
||||
|
||||
Think about it before starting to version your documentation - it can become difficult for contributors to help improve it!
|
||||
|
||||
:::
|
||||
|
||||
Most of the time, you don't need versioning as it will just increase your build time, and introduce complexity to your codebase. Versioning is **best suited for websites with high-traffic and rapid changes to documentation between versions**. If your documentation rarely changes, don't add versioning to your documentation.
|
||||
|
||||
To better understand how versioning works and see if it suits your needs, you can read on below.
|
||||
|
||||
## Overview {#overview}
|
||||
|
||||
A typical versioned doc site looks like below:
|
||||
|
||||
```bash
|
||||
website
|
||||
├── sidebars.json # sidebar for the current docs version
|
||||
├── docs # docs directory for the current docs version
|
||||
│ ├── foo
|
||||
│ │ └── bar.md # https://mysite.com/docs/next/foo/bar
|
||||
│ └── hello.md # https://mysite.com/docs/next/hello
|
||||
├── versions.json # file to indicate what versions are available
|
||||
├── versioned_docs
|
||||
│ ├── version-1.1.0
|
||||
│ │ ├── foo
|
||||
│ │ │ └── bar.md # https://mysite.com/docs/foo/bar
|
||||
│ │ └── hello.md
|
||||
│ └── version-1.0.0
|
||||
│ ├── foo
|
||||
│ │ └── bar.md # https://mysite.com/docs/1.0.0/foo/bar
|
||||
│ └── hello.md
|
||||
├── versioned_sidebars
|
||||
│ ├── version-1.1.0-sidebars.json
|
||||
│ └── version-1.0.0-sidebars.json
|
||||
├── docusaurus.config.js
|
||||
└── package.json
|
||||
```
|
||||
|
||||
The `versions.json` file is a list of version names, ordered from newest to oldest.
|
||||
|
||||
The table below explains how a versioned file maps to its version and the generated URL.
|
||||
|
||||
| Path | Version | URL |
|
||||
| --------------------------------------- | -------------- | ----------------- |
|
||||
| `versioned_docs/version-1.0.0/hello.md` | 1.0.0 | /docs/1.0.0/hello |
|
||||
| `versioned_docs/version-1.1.0/hello.md` | 1.1.0 (latest) | /docs/hello |
|
||||
| `docs/hello.md` | current | /docs/next/hello |
|
||||
|
||||
:::tip
|
||||
|
||||
The files in the `docs` directory belong to the `current` docs version.
|
||||
|
||||
By default, the `current` docs version is labeled as `Next` and hosted under `/docs/next/*`, but it is entirely configurable to fit your project's release lifecycle.
|
||||
|
||||
:::
|
||||
|
||||
### Terminology {#terminology}
|
||||
|
||||
Note the terminology we use here.
|
||||
|
||||
<dl>
|
||||
<dt><b>Current version</b></dt>
|
||||
<dd>The version placed in the <code>./docs</code> folder.</dd>
|
||||
<dt><b>Latest version / last version</b></dt>
|
||||
<dd>The version served by default for docs navbar items. Usually has path <code>/docs</code>.</dd>
|
||||
</dl>
|
||||
|
||||
Current version is defined by the **file system location**, while latest version is defined by the **the navigation behavior**. They may or may not be the same version! (And the default configuration, as shown in the table above, would treat them as different: current version at `/docs/next` and latest at `/docs`.)
|
||||
|
||||
## Tutorials {#tutorials}
|
||||
|
||||
### Tagging a new version {#tagging-a-new-version}
|
||||
|
||||
1. First, make sure the current docs version (the `./docs` directory) is ready to be frozen.
|
||||
2. Enter a new version number.
|
||||
|
||||
```bash npm2yarn
|
||||
npm run docusaurus docs:version 1.1.0
|
||||
```
|
||||
|
||||
When tagging a new version, the document versioning mechanism will:
|
||||
|
||||
- Copy the full `docs/` folder contents into a new `versioned_docs/version-[versionName]/` folder.
|
||||
- Create a versioned sidebars file based from your current [sidebar](docs-introduction.md#sidebar) configuration (if it exists) - saved as `versioned_sidebars/version-[versionName]-sidebars.json`.
|
||||
- Append the new version number to `versions.json`.
|
||||
|
||||
### Creating new docs {#creating-new-docs}
|
||||
|
||||
1. Place the new file into the corresponding version folder.
|
||||
2. Include the reference to the new file in the corresponding sidebar file according to the version number.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Current version structure">
|
||||
|
||||
```bash
|
||||
# The new file.
|
||||
docs/new.md
|
||||
|
||||
# Edit the corresponding sidebar file.
|
||||
sidebar.js
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="Older version structure">
|
||||
|
||||
```bash
|
||||
# The new file.
|
||||
versioned_docs/version-1.0.0/new.md
|
||||
|
||||
# Edit the corresponding sidebar file.
|
||||
versioned_sidebars/version-1.0.0-sidebars.json
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Updating an existing version {#updating-an-existing-version}
|
||||
|
||||
You can update multiple docs versions at the same time because each directory in `versioned_docs/` represents specific routes when published.
|
||||
|
||||
1. Edit any file.
|
||||
2. Commit and push changes.
|
||||
3. It will be published to the version.
|
||||
|
||||
Example: When you change any file in `versioned_docs/version-2.6/`, it will only affect the docs for version `2.6`.
|
||||
|
||||
### Deleting an existing version {#deleting-an-existing-version}
|
||||
|
||||
You can delete/remove versions as well.
|
||||
|
||||
1. Remove the version from `versions.json`.
|
||||
|
||||
Example:
|
||||
|
||||
```diff
|
||||
[
|
||||
"2.0.0",
|
||||
"1.9.0",
|
||||
// highlight-next-line
|
||||
- "1.8.0"
|
||||
]
|
||||
```
|
||||
|
||||
2. Delete the versioned docs directory. Example: `versioned_docs/version-1.8.0`.
|
||||
3. Delete the versioned sidebars file. Example: `versioned_sidebars/version-1.8.0-sidebars.json`.
|
||||
|
||||
## Configuring versioning behavior {#configuring-versioning-behavior}
|
||||
|
||||
The "current" version is the version name for the `./docs` folder. There are different ways to manage versioning, but two very common patterns are:
|
||||
|
||||
- You release v1, and start immediately working on v2 (including its docs). In this case, the **current version** is v2, which is in the `./docs` folder, while the **latest version** is v1, which is the version hosted at `example.com/docs` and is browsed by most of your users.
|
||||
- You release v1, and will maintain it for some time before thinking about v2. In this case, the **current version** and **latest version** will both be point to v1, since the v2 docs doesn't even exist yet!
|
||||
|
||||
Docusaurus defaults work great for the first use case. We will label the current version as "next" and you can even choose not to publish it.
|
||||
|
||||
**For the 2nd use case**: if you release v1 and don't plan to work on v2 anytime soon, instead of versioning v1 and having to maintain the docs in 2 folders (`./docs` + `./versioned_docs/version-1.0.0`), you may consider "pretending" that the current version is a cut version by giving it a path and a label:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@docusaurus/preset-classic',
|
||||
docs: {
|
||||
// highlight-start
|
||||
lastVersion: 'current',
|
||||
versions: {
|
||||
current: {
|
||||
label: '1.0.0',
|
||||
path: '1.0.0',
|
||||
},
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
The docs in `./docs` will be served at `/docs/1.0.0` instead of `/docs/next`, and `1.0.0` will become the default version we link to in the navbar dropdown, and you will only need to maintain a single `./docs` folder.
|
||||
|
||||
We offer these plugin options to customize versioning behavior:
|
||||
|
||||
- `disableVersioning`: Explicitly disable versioning even with versions. This will make the site only include the current version.
|
||||
- `includeCurrentVersion`: Include the current version (the `./docs` folder) of your docs.
|
||||
- **Tip**: turn it off if the current version is a work-in-progress, not ready to be published.
|
||||
- `lastVersion`: Sets which version "latest version" (the `/docs` route) refers to.
|
||||
- **Tip**: `lastVersion: 'current'` makes sense if your current version refers to a major version that's constantly patched and released. The actual route base path and label of the latest version are configurable.
|
||||
- `onlyIncludeVersions`: Defines a subset of versions from `versions.json` to be deployed.
|
||||
- **Tip**: limit to 2 or 3 versions in dev and deploy previews to improve startup and build time.
|
||||
- `versions`: A dictionary of version metadata. For each version, you can customize the following:
|
||||
- `label`: the label displayed in the versions dropdown and banner.
|
||||
- `path`: the route base path of this version. By default, latest version has `/` and current version has `/next`.
|
||||
- `banner`: one of `'none'`, `'unreleased'`, and `'unmaintained'`. Determines what's displayed at the top of every doc page. Any version above the latest version would be "unreleased", and any version below would be "unmaintained".
|
||||
- `badge`: show a badge with the version name at the top of a doc of that version.
|
||||
- `className`: add a custom `className` to the `<html>` element of doc pages of that version.
|
||||
|
||||
See [docs plugin configuration](../../api/plugins/plugin-content-docs.md#configuration) for more details.
|
||||
|
||||
## Navbar items {#navbar-items}
|
||||
|
||||
We offer several navbar items to help you quickly set up navigation without worrying about versioned routes.
|
||||
|
||||
- [`doc`](../../api/themes/theme-configuration.md#navbar-doc-link): a link to a doc.
|
||||
- [`docSidebar`](../../api/themes/theme-configuration.md#navbar-doc-sidebar): a link to the first item in a sidebar.
|
||||
- [`docsVersion`](../../api/themes/theme-configuration.md#navbar-docs-version): a link to the main doc of the currently viewed version.
|
||||
- [`docsVersionDropdown`](../../api/themes/theme-configuration.md#navbar-docs-version-dropdown): a dropdown containing all the versions available.
|
||||
|
||||
These links would all look for an appropriate version to link to, in the following order:
|
||||
|
||||
1. **Active version**: the version that the user is currently browsing, if she is on a page provided by this doc plugin. If she's not on a doc page, fall back to...
|
||||
2. **Preferred version**: the version that the user last viewed. If there's no history, fall back to...
|
||||
3. **Latest version**: the default version that we navigate to, configured by the `lastVersion` option.
|
||||
|
||||
## Recommended practices {#recommended-practices}
|
||||
|
||||
### Version your documentation only when needed {#version-your-documentation-only-when-needed}
|
||||
|
||||
For example, you are building documentation for your npm package `foo` and you are currently in version 1.0.0. You then release a patch version for a minor bug fix and it's now 1.0.1.
|
||||
|
||||
Should you cut a new documentation version 1.0.1? **You probably shouldn't**. 1.0.1 and 1.0.0 docs shouldn't differ according to semver because there are no new features!. Cutting a new version for it will only just create unnecessary duplicated files.
|
||||
|
||||
### Keep the number of versions small {#keep-the-number-of-versions-small}
|
||||
|
||||
As a good rule of thumb, try to keep the number of your versions below 10. You will **very likely** to have a lot of obsolete versioned documentation that nobody even reads anymore. For example, [Jest](https://jestjs.io/versions) is currently in version `27.4`, and only maintains several latest documentation versions with the lowest being `25.X`. Keep it small 😊
|
||||
|
||||
:::tip archive older versions
|
||||
|
||||
If you deploy your site on a Jamstack provider (e.g. [Netlify](../../deployment.mdx)), the provider will save each production build as a snapshot under an immutable URL. You can include archived versions that will never be rebuilt as external links to these immutable URLs. The Jest website and the Docusaurus website both use such pattern to keep the number of actively built versions low.
|
||||
|
||||
:::
|
||||
|
||||
### Use absolute import within the docs {#use-absolute-import-within-the-docs}
|
||||
|
||||
Don't use relative paths import within the docs. Because when we cut a version the paths no longer work (the nesting level is different, among other reasons). You can utilize the `@site` alias provided by Docusaurus that points to the `website` directory. Example:
|
||||
|
||||
```diff
|
||||
- import Foo from '../src/components/Foo';
|
||||
+ import Foo from '@site/src/components/Foo';
|
||||
```
|
||||
|
||||
### Link docs by file paths {#link-docs-by-file-paths}
|
||||
|
||||
Refer to other docs by relative file paths with the `.md` extension, so that Docusaurus can rewrite them to actual URL paths during building. Files will be linked to the correct corresponding version.
|
||||
|
||||
```md
|
||||
The [@hello](hello.md#paginate) document is great!
|
||||
|
||||
See the [Tutorial](../getting-started/tutorial.md) for more info.
|
||||
```
|
||||
|
||||
### Global or versioned collocated assets {#global-or-versioned-collocated-assets}
|
||||
|
||||
You should decide if assets like images and files are per-version or shared between versions.
|
||||
|
||||
If your assets should be versioned, put them in the docs version, and use relative paths:
|
||||
|
||||
```md
|
||||

|
||||
|
||||
[download this file](./file.pdf)
|
||||
```
|
||||
|
||||
If your assets are global, put them in `/static` and use absolute paths:
|
||||
|
||||
```md
|
||||

|
||||
|
||||
[download this file](/file.pdf)
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue