mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-16 01:32:37 +02:00
docs: split sidebar documentation into sections (#6450)
* docs: split sidebar documentation into sections * set slugs * fix links
This commit is contained in:
parent
8140560332
commit
01676329e1
9 changed files with 1139 additions and 1118 deletions
|
@ -98,7 +98,7 @@ Read more about [importing partial pages](../markdown-features/markdown-features
|
|||
|
||||
## 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.md). Tags are passed in the front matter as a list of labels:
|
||||
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"
|
||||
---
|
||||
|
|
|
@ -9,7 +9,7 @@ The `@docusaurus/plugin-content-docs` plugin can support [multi-instance](../../
|
|||
|
||||
:::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.md#using-multiple-sidebars), you can do so within one plugin.
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
374
website/docs/guides/docs/sidebar/autogenerated.md
Normal file
374
website/docs/guides/docs/sidebar/autogenerated.md
Normal file
|
@ -0,0 +1,374 @@
|
|||
---
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
## Autogenerated sidebar metadata {#autogenerated-sidebar-metadata}
|
||||
|
||||
For hand-written 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 files and folders names).
|
||||
|
||||
**For docs**: use additional front matter. The `label` and `className` attributes now become `sidebar_label` and `sidebar_class_name`, while there's an additional `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.
|
||||
|
||||
:::
|
||||
|
||||
:::info
|
||||
|
||||
The position metadata is only used **within a sidebar slice**: Docusaurus does not re-order other items of your sidebar.
|
||||
|
||||
:::
|
||||
|
||||
## 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
|
||||
|
||||
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,
|
||||
}) {
|
||||
// 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
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
:::
|
170
website/docs/guides/docs/sidebar/index.md
Normal file
170
website/docs/guides/docs/sidebar/index.md
Normal file
|
@ -0,0 +1,170 @@
|
|||
---
|
||||
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'),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
### 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
|
||||
|
||||
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 */
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## 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>
|
||||
```
|
437
website/docs/guides/docs/sidebar/items.md
Normal file
437
website/docs/guides/docs/sidebar/items.md
Normal file
|
@ -0,0 +1,437 @@
|
|||
---
|
||||
toc_max_heading_level: 4
|
||||
slug: /sidebar/items
|
||||
---
|
||||
|
||||
# Sidebar items
|
||||
|
||||
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
|
||||
- **[\*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
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
:::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.
|
||||
|
||||
:::
|
||||
|
||||
## 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
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
## 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',
|
||||
},
|
||||
// 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.
|
||||
|
||||
:::
|
||||
|
||||
### 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:
|
||||
|
||||
```js
|
||||
// =================
|
||||
// This item:
|
||||
// =================
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'myDoc',
|
||||
};
|
||||
// =================
|
||||
// Is equivalent to:
|
||||
// =================
|
||||
'myDoc';
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```js
|
||||
// ===================
|
||||
// This item:
|
||||
// ===================
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting started',
|
||||
items: ['doc1', 'doc2'],
|
||||
};
|
||||
// ===================
|
||||
// Is equivalent to:
|
||||
// ===================
|
||||
{
|
||||
'Getting started': ['doc1', 'doc2'],
|
||||
};
|
||||
```
|
||||
|
||||
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).
|
142
website/docs/guides/docs/sidebar/multiple-sidebars.md
Normal file
142
website/docs/guides/docs/sidebar/multiple-sidebars.md
Normal file
|
@ -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)
|
|
@ -476,7 +476,7 @@ If you want to keep the `.html` extension as the canonical url of a page, docs c
|
|||
|
||||
### Sidebar {#sidebar}
|
||||
|
||||
In previous version, nested sidebar category is not allowed and sidebar category can only contain doc id. However, v2 allows infinite nested sidebar and we have many types of [Sidebar Item](../guides/docs/sidebar.md#understanding-sidebar-items) other than document.
|
||||
In previous version, nested sidebar category is not allowed and sidebar category can only contain doc id. However, v2 allows infinite nested sidebar and we have many types of [Sidebar Item](../guides/docs/sidebar/items.md) other than document.
|
||||
|
||||
You'll have to migrate your sidebar if it contains category type. Rename `subcategory` to `category` and `ids` to `items`.
|
||||
|
||||
|
|
|
@ -47,7 +47,19 @@ const sidebars = {
|
|||
},
|
||||
items: [
|
||||
'guides/docs/create-doc',
|
||||
'guides/docs/sidebar',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Sidebar',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'guides/docs/sidebar/index',
|
||||
},
|
||||
items: [
|
||||
'guides/docs/sidebar/items',
|
||||
'guides/docs/sidebar/autogenerated',
|
||||
'guides/docs/sidebar/multiple-sidebars',
|
||||
],
|
||||
},
|
||||
'guides/docs/versioning',
|
||||
'guides/docs/markdown-features',
|
||||
'guides/docs/multi-instance',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue