chore(v2): prepare v2.0.0-beta.0 release (#4774)

* beta.0 version docs + changelog

* fix config for beta switch

* v2.0.0-beta.0
This commit is contained in:
Sébastien Lorber 2021-05-12 16:07:15 +02:00 committed by GitHub
parent fe6492aa87
commit 7e4d7671c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
103 changed files with 11779 additions and 149 deletions

View file

@ -0,0 +1,130 @@
---
id: creating-pages
title: Creating Pages
slug: /creating-pages
---
In this section, we will learn about creating pages in Docusaurus.
This is useful for creating **one-off standalone pages** like a showcase page, playground page or support page.
The functionality of pages is powered by `@docusaurus/plugin-content-pages`.
You can use React components, or Markdown.
:::note
Pages do not have sidebars, only [docs](./docs/docs-introduction.md) have.
:::
## Add a React page {#add-a-react-page}
Create a file `/src/pages/helloReact.js`:
```jsx title="/src/pages/helloReact.js"
import React from 'react';
import Layout from '@theme/Layout';
function Hello() {
return (
<Layout title="Hello">
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '50vh',
fontSize: '20px',
}}>
<p>
Edit <code>pages/hello.js</code> and save to reload.
</p>
</div>
</Layout>
);
}
export default Hello;
```
Once you save the file, the development server will automatically reload the changes. Now open `http://localhost:3000/helloReact`, you will see the new page you just created.
Each page doesn't come with any styling. You will need to import the `Layout` component from `@theme/Layout` and wrap your contents within that component if you want the navbar and/or footer to appear.
:::tip
You can also create TypeScript pages with the `.tsx` extension (`helloReact.tsx`).
:::
## Add a Markdown page {#add-a-markdown-page}
Create a file `/src/pages/helloMarkdown.md`:
```mdx title="/src/pages/helloMarkdown.md"
---
title: my hello page title
description: my hello page description
hide_table_of_contents: true
---
# Hello
How are you?
```
In the same way, a page will be created at `http://localhost:3000/helloMarkdown`.
Markdown pages are less flexible than React pages, because it always uses the theme layout.
Here's an [example Markdown page](/examples/markdownPageExample).
:::tip
You can use the full power of React in Markdown pages too, refer to the [MDX](https://mdxjs.com/) documentation.
:::
## Routing {#routing}
If you are familiar with other static site generators like Jekyll and Next, this routing approach will feel familiar to you. Any JavaScript file you create under `/src/pages/` directory will be automatically converted to a website page, following the `/src/pages/` directory hierarchy. For example:
- `/src/pages/index.js``<baseUrl>`
- `/src/pages/foo.js``<baseUrl>/foo`
- `/src/pages/foo/test.js``<baseUrl>/foo/test`
- `/src/pages/foo/index.js``<baseUrl>/foo/`
In this component-based development era, it is encouraged to co-locate your styling, markup and behavior together into components. Each page is a component, and if you need to customize your page design with your own styles, we recommend co-locating your styles with the page component in its own directory. For example, to create a "Support" page, you could do one of the following:
- Add a `/src/pages/support.js` file
- Create a `/src/pages/support/` directory and a `/src/pages/support/index.js` file.
The latter is preferred as it has the benefits of letting you put files related to the page within that directory. For example, a CSS module file (`styles.module.css`) with styles meant to only be used on the "Support" page. **Note:** this is merely a recommended directory structure and you will still need to manually import the CSS module file within your component module (`support/index.js`). By default, any Markdown or Javascript file starting with `_` will be ignored, and no routes will be created for that file (see the `exclude` option).
```sh
my-website
├── src
│ └── pages
│ ├── styles.module.css
│ ├── index.js
| ├──_ignored.js
│ └── support
│ ├── index.js
│ └── styles.module.css
.
```
:::caution
All JavaScript/TypeScript files within the `src/pages/` directory will have corresponding website paths generated for them. If you want to create reusable components into that directory, use the `exclude` option (by default, files prefixed with `_`, test files(`.test.js`) and files in `__tests__` directory are not turned into pages).
:::
## Using React {#using-react}
React is used as the UI library to create pages. Every page component should export a React component, and you can leverage on the expressiveness of React to build rich and interactive content.
## Duplicate Routes {#duplicate-routes}
You may accidentally create multiple pages that are meant to be accessed on the same route. When this happens, Docusaurus will warn you about duplicate routes when you run `yarn start` or `yarn build`, but the site will still be built successfully. The page that was created last will be accessible, but it will override other conflicting pages. To resolve this issue, you should modify or remove any conflicting routes.

View file

@ -0,0 +1,79 @@
---
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.
```yml
---
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
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:
import BrowserWindow from '@site/src/components/BrowserWindow';
<BrowserWindow url="http://localhost:3000">
<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</h3>
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
</BrowserWindow>

View file

@ -0,0 +1,80 @@
---
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.
## 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 user in the front matter. For example, if `guide/hello.md`'s content is defined as below, its final `id` is `guide/part1`.
```yml
---
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`).
```yml
---
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 frontmatter:
```yml
---
id: my-home-doc
slug: /
---
Lorem ipsum
```
## Docs-only mode {#docs-only-mode}
If you only want the documentation feature, you can run your Docusaurus 2 site without a landing page and display your documentation page as the index page instead.
To enable docs-only mode, set the docs plugin `routeBasePath: '/'`, and use the frontmatter `slug: /` on the document that should be the index page ([more infos](#home-page-docs)).
:::caution
You should delete the existing homepage at `./src/pages/index.js`, or else there will be two files mapping to the same route!
:::
:::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.md#blog-only-mode).
:::

View file

@ -0,0 +1,28 @@
---
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 frontmatter {#markdown-frontmatter}
Markdown docs have their own [Markdown frontmatter](../../api/plugins/plugin-content-docs.md#markdown-frontmatter)
## Referencing other documents {#referencing-other-documents}
If you want to reference another document file, you could use the name of the document you want to reference. Docusaurus will convert the file path to be the final website path (and remove the `.md`).
For example, if you are in `doc2.md` and you want to reference `doc1.md` and `folder/doc3.md`:
```md
I am referencing a [document](doc1.md). Reference to another [document in a folder](folder/doc3.md).
[Relative document](../doc2.md) referencing works as well.
```
One benefit of this approach is that the links to external files will still work if you are viewing the file on GitHub.
Another benefit, for versioned docs, is that one versioned doc will link to another doc of the exact same version.

View file

@ -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 documentations](./versioning.md). It is recommended to be familiar with docs versioning before reading this page.
:::
## 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 such 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
},
],
},
},
};
```

View file

@ -0,0 +1,634 @@
---
id: sidebar
title: Sidebar
slug: /sidebar
---
Creating a sidebar is useful to:
- Group multiple **related documents**
- **Display a sidebar** on each of those documents
- Provide a **paginated navigation**, with next/previous button
To use sidebars on your Docusaurus site:
1. Define a file that exports a [sidebar object](#sidebar-object).
1. 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-start
sidebarPath: require.resolve('./sidebars.js'),
// highlight-end
},
},
],
],
};
```
## Default sidebar
By default, Docusaurus [automatically generates a sidebar](#sidebar-item-autogenerated) for you, by using the filesystem structure of the `docs` folder:
```js title="sidebars.js"
module.exports = {
mySidebar: [
{
type: 'autogenerated',
dirName: '.', // generate sidebar slice from the docs folder (or versioned_docs/<version>)
},
],
};
```
You can also define your sidebars explicitly.
## Sidebar object {#sidebar-object}
A sidebar is a **tree of [sidebar items](#understanding-sidebar-items)**.
```typescript
type Sidebar =
// Normal syntax
| SidebarItem[]
// Shorthand syntax
| Record<
string, // category label
SidebarItem[] // category items
>;
```
A sidebars file can contain **multiple sidebar objects**.
```typescript
type SidebarsFile = Record<
string, // sidebar id
Sidebar
>;
```
Example:
```js title="sidebars.js"
module.exports = {
mySidebar: [
{
type: 'category',
label: 'Getting Started',
items: ['doc1'],
},
{
type: 'category',
label: 'Docusaurus',
items: ['doc2', 'doc3'],
},
],
};
```
Notice the following:
- There is a single sidebar `mySidebar`, containing 5 [sidebar items](#understanding-sidebar-items)
- `Getting Started` and `Docusaurus` are sidebar categories
- `doc1`, `doc2` and `doc3` are sidebar documents
:::tip
Use the **shorthand syntax** to express this sidebar more concisely:
```js title="sidebars.js"
module.exports = {
mySidebar: {
'Getting started': ['doc1'],
Docusaurus: ['doc2', 'doc3'],
},
};
```
:::
## Using 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)
:::
Example:
```js title="sidebars.js"
module.exports = {
tutorialSidebar: {
'Category A': ['doc1', 'doc2'],
},
apiSidebar: ['doc3', 'doc4'],
};
```
:::note
The keys `tutorialSidebar` and `apiSidebar` are sidebar **technical ids** and do not matter much.
:::
When browsing:
- `doc1` or `doc2`: the `tutorialSidebar` will be displayed
- `doc3` or `doc4`: the `apiSidebar` will be displayed
A **paginated navigation** link documents inside the same sidebar with **next and previous buttons**.
## Understanding sidebar items {#understanding-sidebar-items}
`SidebarItem` is an item defined in a Sidebar tree.
There are different types of sidebar items:
- **[Doc](#sidebar-item-doc)**: link to a doc page, assigning it to the sidebar
- **[Ref](#sidebar-item-ref)**: link to a doc page, without assigning it to the sidebar
- **[Link](#sidebar-item-link)**: link to any internal or external page
- **[Category](#sidebar-item-category)**: create a hierarchy of sidebar items
- **[Autogenerated](#sidebar-item-autogenerated)**: generate a sidebar slice automatically
### 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:
```typescript
type SidebarItemDoc =
// Normal syntax
| {
type: 'doc';
id: string;
label: string; // Sidebar label text
}
// 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
],
};
```
The `sidebar_label` markdown frontmatter has a higher precedence over the `label` key in `SidebarItemDoc`.
:::note
Don't assign the same doc to multiple sidebars: use a [ref](#sidebar-item-ref) instead.
:::
### Ref: link to a doc, without sidebar {#sidebar-item-ref}
Use the `ref` type to link to a doc page without assigning it to a sidebar.
```typescript
type SidebarItemRef = {
type: 'ref';
id: string;
};
```
Example:
```js title="sidebars.js"
module.exports = {
mySidebar: [
{
type: 'ref',
id: 'doc1', // Document id (string).
},
],
};
```
When browsing `doc1`, Docusaurus **will not display** the `mySidebar` sidebar.
### 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.
```typescript
type SidebarItemLink = {
type: 'link';
label: string;
href: 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.
```typescript
type SidebarItemCategory = {
type: 'category';
label: string; // Sidebar label text.
items: SidebarItem[]; // Array of sidebar items.
// Category options:
collapsed: boolean; // Set the category to be collapsed or open by default
};
```
Example:
```js title="sidebars.js"
module.exports = {
docs: [
{
type: 'category',
label: 'Guides',
collapsed: false,
items: [
'creating-pages',
{
type: 'category',
label: 'Docs',
items: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
},
],
},
],
};
```
:::tip
Use the **shorthand syntax** when you don't need **category options**:
```js title="sidebars.js"
module.exports = {
docs: {
Guides: [
'creating-pages',
{
Docs: ['introduction', 'sidebar', 'markdown-features', 'versioning'],
},
],
},
};
```
:::
#### Collapsible categories {#collapsible-categories}
For sites with a sizable amount of content, we support the option to expand/collapse a category to toggle the display of its contents. Categories are collapsible by default. If you want them to be always expanded, set `themeConfig.sidebarCollapsible` to `false`:
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
// highlight-start
sidebarCollapsible: false,
// highlight-end
},
};
```
#### Expanded categories by default {#expanded-categories-by-default}
For docs that have collapsible categories, you may want more fine-grain control over certain categories. If you want specific categories to be always expanded, you can set `collapsed` to `false`:
```js title="sidebars.js"
module.exports = {
docs: {
Guides: [
'creating-pages',
{
type: 'category',
label: 'Docs',
collapsed: false,
items: ['markdown-features', 'sidebar', 'versioning'],
},
],
},
};
```
### Autogenerated: generate a sidebar {#sidebar-item-autogenerated}
Docusaurus can **create a sidebar automatically** from your **filesystem structure**: each folder creates a sidebar category.
An `autogenerated` item is converted by Docusaurus to a **sidebar slice**: a list of items of type `doc` and `category`.
```typescript
type SidebarItemAutogenerated = {
type: 'autogenerated';
dirName: string; // Source folder to generate the sidebar slice from (relative to docs)
};
```
Docusaurus can generate a sidebar from your docs folder:
```js title="sidebars.js"
module.exports = {
myAutogeneratedSidebar: [
// highlight-start
{
type: 'autogenerated',
dirName: '.', // '.' means the current docs folder
},
// highlight-end
],
};
```
You can also use **multiple `autogenerated` items** in a sidebar, and interleave them with regular sidebar items:
```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: 'guides', // Generate sidebar slice from docs/guides
},
// highlight-end
{
type: 'category',
label: 'Community',
items: ['team', 'chat'],
},
],
};
```
#### Autogenerated sidebar metadatas {#autogenerated-sidebar-metadatas}
By default, the sidebar slice will be generated in **alphabetical order** (using files and folders names).
If the generated sidebar does not look good, you can assign additional metadatas to docs and categories.
**For docs**: use additional frontmatter:
```diff title="docs/tutorials/tutorial-easy.md"
+ ---
+ sidebar_label: Easy
+ sidebar_position: 2
+ ---
# Easy Tutorial
This is the easy tutorial!
```
**For categories**: add a `_category_.json` or `_category_.yml` file in the appropriate folder:
```json title="docs/tutorials/_category_.json"
{
"label": "Tutorial",
"position": 3
}
```
```yaml title="docs/tutorials/_category_.yml"
label: 'Tutorial'
position: 2.5 # float position is supported
collapsed: false # keep the category open by default
```
:::info
The position metadata is only used **inside 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:
```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 metadatas](#autogenerated-sidebar-metadatas)**.
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
sidebarItemsGenerator: async function ({
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.
**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
sidebarItemsGenerator: async function ({
defaultSidebarItemsGenerator,
...args
}) {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return reverseSidebarItems(sidebarItems);
},
// highlight-end
},
],
],
};
```
:::
## Hideable sidebar {#hideable-sidebar}
Using the enabled `themeConfig.hideableSidebar` option, you can make the entire sidebar hidden, allowing you to better focus your users on the content. This is especially useful when content consumption on medium screens (e.g. on tablets).
```js title="docusaurus.config.js"
module.exports = {
themeConfig: {
// highlight-starrt
hideableSidebar: true,
// highlight-end
},
};
```
## 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}
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>
```

View file

@ -0,0 +1,208 @@
---
id: versioning
title: Versioning
slug: /versioning
---
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.
## Directory structure {#directory-structure}
```shell
website
├── sidebars.json # sidebar for master (next) version
├── docs # docs directory for master (next) 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 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` | next | /docs/next/hello |
### Tagging a new version {#tagging-a-new-version}
1. First, make sure your content in the `docs` directory is ready to be frozen as a version. A version always should be based from master.
1. 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-<version>/` folder.
- Create a versioned sidebars file based from your current [sidebar](docs-introduction.md#sidebar) configuration (if it exists) - saved as `versioned_sidebars/version-<version>-sidebars.json`.
- Append the new version number to `versions.json`.
## Docs {#docs}
### Creating new docs {#creating-new-docs}
1. Place the new file into the corresponding version folder.
1. Include the reference for the new file into the corresponding sidebar file, according to version number.
**Master docs**
```shell
# The new file.
docs/new.md
# Edit the corresponding sidebar file.
sidebar.js
```
**Older docs**
```shell
# The new file.
versioned_docs/version-1.0.0/new.md
# Edit the corresponding sidebar file.
versioned_sidebars/version-1.0.0-sidebars.json
```
### Linking docs {#linking-docs}
- Remember to include the `.md` extension.
- Files will be linked to correct corresponding version.
- Relative paths work as well.
```md
The [@hello](hello.md#paginate) document is great!
See the [Tutorial](../getting-started/tutorial.md) for more info.
```
## Versions {#versions}
Each directory in `versioned_docs/` will represent a documentation version.
### 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.
1. Commit and push changes.
1. 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 {4}
[
"2.0.0",
"1.9.0",
- "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`.
## Recommended practices {#recommended-practices}
### Figure out the behavior for the "current" version {#figure-out-the-behavior-for-the-current-version}
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)
- You release v1, and will maintain it for some time before thinking about v2.
Docusaurus defaults work great for the first usecase.
**For the 2nd usecase**: 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 using the following configuration instead:
```json
{
"lastVersion": "current",
"versions": {
"current": {
"label": "1.0.0",
"path": "1.0.0"
}
}
}
```
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.
See [docs plugin configuration](../../api/plugins/plugin-content-docs.md) for more details.
### Version your documentation only when needed {#version-your-documentation-only-when-needed}
For example, you are building a 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. **It is very likely** that you will have a lot of obsolete versioned documentation that nobody even reads anymore. For example, [Jest](https://jestjs.io/versions) is currently in version `24.9`, and only maintains several latest documentation version with the lowest being `22.X`. Keep it small 😊
### 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';
```
### Global or versioned colocated assets {#global-or-versioned-colocated-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
![img alt](./myImage.png)
[download this file](./file.pdf)
```
If your assets are global, put them in `/static` and use absolute paths:
```md
![img alt](/myImage.png)
[download this file](/file.pdf)
```

View file

@ -0,0 +1,86 @@
---
id: admonitions
title: Admonitions
description: Handling admonitions/callouts in Docusaurus Markdown
slug: /markdown-features/admonitions
---
In addition to the basic Markdown syntax, we use [remark-admonitions](https://github.com/elviswolcott/remark-admonitions) alongside MDX to add support for admonitions. Admonitions are wrapped by a set of 3 colons.
Example:
:::note
The content and title *can* include markdown.
:::
:::tip You can specify an optional title
Heads up! Here's a pro-tip.
:::
:::info
Useful information.
:::
:::caution
Warning! You better pay attention!
:::
:::danger
Danger danger, mayday!
:::
:::note
The content and title _can_ include markdown.
:::
:::tip You can specify an optional title
Heads up! Here's a pro-tip.
:::
:::info
Useful information.
:::
:::caution
Warning! You better pay attention!
:::
:::danger
Danger danger, mayday!
:::
## Specifying title {#specifying-title}
You may also specify an optional title
:::note Your Title
The content and title *can* include markdown.
:::
:::note Your Title
The content and title _can_ include Markdown.
:::

View file

@ -0,0 +1,147 @@
---
id: assets
title: Assets
description: Handling assets in Docusaurus Markdown
slug: /markdown-features/assets
---
Sometimes you want to link to static assets directly from Markdown files, and it is convenient to co-locate the asset next to the markdown file using it.
We have setup Webpack loaders to handle most common file types, so that when you import a file, you get its url, and the asset is automatically copied to the output folder.
Let's imagine the following file structure:
```
# Your doc
/website/docs/myFeature.mdx
# Some assets you want to use
/website/docs/assets/docusaurus-asset-example-banner.png
/website/docs/assets/docusaurus-asset-example-pdf.pdf
```
## Images {#images}
You can use images in Markdown, or by requiring them and using a JSX image tag:
```mdx
# My Markdown page
<img
src={require('./assets/docusaurus-asset-example-banner.png').default}
alt="Example banner"
/>
or
![Example banner](./assets/docusaurus-asset-example-banner.png)
```
The ES imports syntax also works:
```mdx
# My Markdown page
import myImageUrl from './assets/docusaurus-asset-example-banner.png';
<img src={myImageUrl} alt="My image alternative text" />
```
This results in displaying the image:
![My image alternative text](../../assets/docusaurus-asset-example-banner.png)
:::note
If you are using [@docusaurus/plugin-ideal-image](../../using-plugins.md#docusaurusplugin-ideal-image), you need to use the dedicated image component, as documented.
:::
## Files {#files}
In the same way, you can link to existing assets by requiring them and using the returned url in videos, links etc.
```mdx
# My Markdown page
<a
target="_blank"
href={require('./assets/docusaurus-asset-example-pdf.pdf').default}>
Download this PDF
</a>
or
[Download this PDF using Markdown](./assets/docusaurus-asset-example-pdf.pdf)
```
<a
target="_blank"
href={require('../../assets/docusaurus-asset-example-pdf.pdf').default}>
Download this PDF
</a>
[Download this PDF using Markdown](../../assets/docusaurus-asset-example-pdf.pdf)
## Inline SVGs {#inline-svgs}
Docusaurus supports inlining SVGs out of the box.
```jsx
import DocusaurusSvg from './docusaurus.svg';
<DocusaurusSvg />;
```
import DocusaurusSvg from '@site/static/img/docusaurus.svg';
<DocusaurusSvg />
This can be useful, if you want to alter the part of the SVG image via CSS. For example, you can change one of the SVG colors based on the current theme.
```jsx
import DocusaurusSvg from './docusaurus.svg';
<DocusaurusSvg className="themedDocusaurus" />;
```
```css
html[data-theme='light'] .themedDocusaurus [fill='#FFFF50'] {
fill: greenyellow;
}
html[data-theme='dark'] .themedDocusaurus [fill='#FFFF50'] {
fill: seagreen;
}
```
<DocusaurusSvg className="themedDocusaurus" />
## Themed Images {#themed-images}
Docusaurus supports themed images: the `ThemedImage` component (included in the classic/bootstrap themes) allows you to switch the image source based on the current theme.
```jsx {5-8}
import ThemedImage from '@theme/ThemedImage';
<ThemedImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl('/img/docusaurus_light.svg'),
dark: useBaseUrl('/img/docusaurus_dark.svg'),
}}
/>;
```
```mdx-code-block
import useBaseUrl from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';
<ThemedImage
alt="Docusaurus themed image"
sources={{
light: useBaseUrl('/img/docusaurus_keytar.svg'),
dark: useBaseUrl('/img/docusaurus_speed.svg'),
}}
/>
```

View file

@ -0,0 +1,449 @@
---
id: code-blocks
title: Code blocks
description: Handling code blocks in Docusaurus Markdown
slug: /markdown-features/code-blocks
---
Code blocks within documentation are super-powered 💪.
## Code title {#code-title}
You can add a title to the code block by adding `title` key after the language (leave a space between them).
```jsx title="/src/components/HelloCodeTitle.js"
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
```
```jsx title="/src/components/HelloCodeTitle.js"
function HelloCodeTitle(props) {
return <h1>Hello, {props.name}</h1>;
}
```
## Syntax highlighting {#syntax-highlighting}
Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://github.com/mdx-js/specification) for specifications of MDX.
```jsx
console.log('Every repo must come with a mascot.');
```
<!-- TODO: We need to allow users to pick syntax highlighting themes (maybe other than swizzling) -->
Use the matching language meta string for your code block, and Docusaurus will pick up syntax highlighting automatically, powered by [Prism React Renderer](https://github.com/FormidableLabs/prism-react-renderer).
```jsx
console.log('Every repo must come with a mascot.');
```
By default, the Prism [syntax highlighting theme](https://github.com/FormidableLabs/prism-react-renderer#theming) we use is [Palenight](https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/themes/palenight.js). You can change this to another theme by passing `theme` field in `prism` as `themeConfig` in your docusaurus.config.js.
For example, if you prefer to use the `dracula` highlighting theme:
```js {4} title="docusaurus.config.js"
module.exports = {
themeConfig: {
prism: {
theme: require('prism-react-renderer/themes/dracula'),
},
},
};
```
By default, Docusaurus comes with a subset of [commonly used languages](https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/vendor/prism/includeLangs.js).
:::caution
Some popular languages like Java, C#, or PHP are not enabled by default.
:::
To add syntax highlighting for any of the other [Prism supported languages](https://prismjs.com/#supported-languages), define it in an array of additional languages.
For example, if you want to add highlighting for the `powershell` language:
```js {5} title="docusaurus.config.js"
module.exports = {
// ...
themeConfig: {
prism: {
additionalLanguages: ['powershell'],
},
// ...
},
};
```
If you want to add highlighting for languages not yet supported by Prism, you can swizzle `prism-include-languages`:
```bash npm2yarn
npm run swizzle @docusaurus/theme-classic prism-include-languages
```
It will produce `prism-include-languages.js` in your `src/theme` folder. You can add highlighting support for custom languages by editing `prism-include-languages.js`:
```js {8} title="src/theme/prism-include-languages.js"
const prismIncludeLanguages = (Prism) => {
// ...
additionalLanguages.forEach((lang) => {
require(`prismjs/components/prism-${lang}`); // eslint-disable-line
});
require('/path/to/your/prism-language-definition');
// ...
};
```
You can refer to [Prism's official language definitions](https://github.com/PrismJS/prism/tree/master/components) when you are writing your own language definitions.
## Line highlighting {#line-highlighting}
You can bring emphasis to certain lines of code by specifying line ranges after the language meta string (leave a space after the language).
```jsx {3}
function HighlightSomeText(highlight) {
if (highlight) {
return 'This text is highlighted!';
}
return 'Nothing highlighted';
}
```
```jsx {3}
function HighlightSomeText(highlight) {
if (highlight) {
return 'This text is highlighted!';
}
return 'Nothing highlighted';
}
```
To accomplish this, Docusaurus adds the `docusaurus-highlight-code-line` class to the highlighted lines. You will need to define your own styling for this CSS, possibly in your `src/css/custom.css` with a custom background color which is dependent on your selected syntax highlighting theme. The color given below works for the default highlighting theme (Palenight), so if you are using another theme, you will have to tweak the color accordingly.
```css title="/src/css/custom.css"
.docusaurus-highlight-code-line {
background-color: rgb(72, 77, 91);
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
/* If you have a different syntax highlighting theme for dark mode. */
html[data-theme='dark'] .docusaurus-highlight-code-line {
background-color: ; /* Color which works with dark mode syntax highlighting theme */
}
```
To highlight multiple lines, separate the line numbers by commas or use the range syntax to select a chunk of lines. This feature uses the `parse-number-range` library and you can find [more syntax](https://www.npmjs.com/package/parse-numeric-range) on their project details.
```jsx {1,4-6,11}
import React from 'react';
function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>;
}
export default MyComponent;
```
```jsx {1,4-6,11}
import React from 'react';
function MyComponent(props) {
if (props.isBar) {
return <div>Bar</div>;
}
return <div>Foo</div>;
}
export default MyComponent;
```
You can also use comments with `highlight-next-line`, `highlight-start`, and `highlight-end` to select which lines are highlighted.
```jsx
function HighlightSomeText(highlight) {
if (highlight) {
// highlight-next-line
return 'This text is highlighted!';
}
return 'Nothing highlighted';
}
function HighlightMoreText(highlight) {
// highlight-start
if (highlight) {
return 'This range is highlighted!';
}
// highlight-end
return 'Nothing highlighted';
}
```
```jsx
function HighlightSomeText(highlight) {
if (highlight) {
// highlight-next-line
return 'This text is highlighted!';
}
return 'Nothing highlighted';
}
function HighlightMoreText(highlight) {
// highlight-start
if (highlight) {
return 'This range is highlighted!';
}
// highlight-end
return 'Nothing highlighted';
}
```
Supported commenting syntax:
| Language | Syntax |
| ---------- | ------------------------ |
| JavaScript | `/* ... */` and `// ...` |
| JSX | `{/* ... */}` |
| Python | `# ...` |
| HTML | `<!-- ... -->` |
If there's a syntax that is not currently supported, we are open to adding them! Pull requests welcome.
## Interactive code editor {#interactive-code-editor}
(Powered by [React Live](https://github.com/FormidableLabs/react-live))
You can create an interactive coding editor with the `@docusaurus/theme-live-codeblock` plugin.
First, add the plugin to your package.
```bash npm2yarn
npm install --save @docusaurus/theme-live-codeblock
```
You will also need to add the plugin to your `docusaurus.config.js`.
```js {3}
module.exports = {
// ...
themes: ['@docusaurus/theme-live-codeblock'],
// ...
};
```
To use the plugin, create a code block with `live` attached to the language meta string.
```jsx live
function Clock(props) {
const [date, setDate] = useState(new Date());
useEffect(() => {
var timerID = setInterval(() => tick(), 1000);
return function cleanup() {
clearInterval(timerID);
};
});
function tick() {
setDate(new Date());
}
return (
<div>
<h2>It is {date.toLocaleTimeString()}.</h2>
</div>
);
}
```
The code block will be rendered as an interactive editor. Changes to the code will reflect on the result panel live.
```jsx live
function Clock(props) {
const [date, setDate] = useState(new Date());
useEffect(() => {
var timerID = setInterval(() => tick(), 1000);
return function cleanup() {
clearInterval(timerID);
};
});
function tick() {
setDate(new Date());
}
return (
<div>
<h2>It is {date.toLocaleTimeString()}.</h2>
</div>
);
}
```
### Imports {#imports}
:::caution react-live and imports
It is not possible to import components directly from the react-live code editor, you have to define available imports upfront.
:::
By default, all React imports are available. If you need more imports available, swizzle the react-live scope:
```bash npm2yarn
npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope
```
```jsx {3-15,21} title="src/theme/ReactLiveScope/index.js"
import React from 'react';
const ButtonExample = (props) => (
<button
{...props}
style={{
backgroundColor: 'white',
border: 'solid red',
borderRadius: 20,
padding: 10,
cursor: 'pointer',
...props.style,
}}
/>
);
// Add react-live imports you need here
const ReactLiveScope = {
React,
...React,
ButtonExample,
};
export default ReactLiveScope;
```
The `ButtonExample` component is now available to use:
```jsx live
function MyPlayground(props) {
return (
<div>
<ButtonExample onClick={() => alert('hey!')}>Click me</ButtonExample>
</div>
);
}
```
## Multi-language support code blocks {#multi-language-support-code-blocks}
With MDX, you can easily create interactive components within your documentation, for example, to display code in multiple programming languages and switching between them using a tabs component.
Instead of implementing a dedicated component for multi-language support code blocks, we've implemented a generic Tabs component in the classic theme so that you can use it for other non-code scenarios as well.
The following example is how you can have multi-language code tabs in your docs. Note that the empty lines above and below each language block is **intentional**. This is a current limitation of MDX, you have to leave empty lines around Markdown syntax for the MDX parser to know that it's Markdown syntax and not JSX.
````jsx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs
defaultValue="js"
values={[
{ label: 'JavaScript', value: 'js', },
{ label: 'Python', value: 'py', },
{ label: 'Java', value: 'java', },
]
}>
<TabItem value="js">
```js
function helloWorld() {
console.log('Hello, world!');
}
```
</TabItem>
<TabItem value="py">
```py
def hello_world():
print 'Hello, world!'
```
</TabItem>
<TabItem value="java">
```java
class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello, World");
}
}
```
</TabItem>
</Tabs>
````
And you will get the following:
````mdx-code-block
<Tabs
defaultValue="js"
values={[
{ label: 'JavaScript', value: 'js', },
{ label: 'Python', value: 'py', },
{ label: 'Java', value: 'java', },
]
}>
<TabItem value="js">
```js
function helloWorld() {
console.log('Hello, world!');
}
```
</TabItem>
<TabItem value="py">
```py
def hello_world():
print 'Hello, world!'
```
</TabItem>
<TabItem value="java">
```java
class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello, World");
}
}
```
</TabItem>
</Tabs>
````
You may want to implement your own `<MultiLanguageCode />` abstraction if you find the above approach too verbose. We might just implement one in future for convenience.
If you have multiple of these multi-language code tabs, and you want to sync the selection across the tab instances, refer to the [Syncing tab choices section](#syncing-tab-choices).

View file

@ -0,0 +1,59 @@
---
id: headings
title: Headings
description: Using Markdown headings
slug: /markdown-features/headings
---
## Markdown headings {#markdown-headings}
You can use regular Markdown headings.
```
## Level 2 title
### Level 3 title
#### Level 4 title
```
Markdown headings appear as a table-of-contents entry.
## Heading ids {#heading-ids}
Each heading has an id that can be automatically generated, or explicitly specified.
Heading ids allow you to link to a specific document heading in Markdown or JSX:
```md
[link](#heading-id)
```
```jsx
<Link to="#heading-id">link</Link>
```
### Generated ids {#generated-ids}
By default, Docusaurus will generate heading ids for you, based on the heading text.
`### Hello World` will have id `hello-world`.
Generated ids have **some limits**:
- The id might not look good
- You might want to **change or translate** the text without updating the existing id
### Explicit ids {#explicit-ids}
A special Markdown syntax lets you set an **explicit heading id**:
```md
### Hello World {#my-explicit-id}
```
:::tip
Use the **[write-heading-ids](../../cli.md#docusaurus-write-heading-ids-sitedir)** CLI command to add explicit ids to all your Markdown documents.
:::

View file

@ -0,0 +1,121 @@
---
id: inline-toc
title: Inline TOC
description: Using inline table-of-contents inside Docusaurus Markdown
slug: /markdown-features/inline-toc
---
import BrowserWindow from '@site/src/components/BrowserWindow';
Each markdown document displays a tab of content on the top-right corner.
But it is also possible to display an inline table of contents directly inside a markdown document, thanks to MDX.
## Full table of contents {#full-table-of-contents}
The `toc` variable is available in any MDX document, and contain all the top level headings of a MDX document.
```jsx
import TOCInline from '@theme/TOCInline';
<TOCInline toc={toc} />;
```
```mdx-code-block
import TOCInline from '@theme/TOCInline';
<BrowserWindow>
<TOCInline toc={toc} />
</BrowserWindow>
```
## Custom table of contents {#custom-table-of-contents}
The `toc` props is just a list of table of contents items:
```ts
type TOCItem = {
value: string;
id: string;
children: TOCItem[];
};
```
You can create this TOC tree manually, or derive a new TOC tree from the `toc` variable:
```jsx
import TOCInline from '@theme/TOCInline';
<TOCInline
toc={
// Only show 3th and 5th top-level heading
[toc[2], toc[4]]
}
/>;
```
```mdx-code-block
<BrowserWindow>
<TOCInline toc={[toc[2], toc[4]]} />
</BrowserWindow>
```
---
:::caution
The underlying content is just an example to have more table-of-contents items available in current page.
:::
## Example Section 1 {#example-section-1}
Lorem ipsum
### Example Subsection 1 a {#example-subsection-1-a}
Lorem ipsum
### Example Subsection 1 b {#example-subsection-1-b}
Lorem ipsum
### Example Subsection 1 c {#example-subsection-1-c}
Lorem ipsum
## Example Section 2 {#example-section-2}
Lorem ipsum
### Example Subsection 2 a {#example-subsection-2-a}
Lorem ipsum
### Example Subsection 2 b {#example-subsection-2-b}
Lorem ipsum
### Example Subsection 2 c {#example-subsection-2-c}
Lorem ipsum
## Example Section 3 {#example-section-3}
Lorem ipsum
### Example Subsection 3 a {#example-subsection-3-a}
Lorem ipsum
### Example Subsection 3 b {#example-subsection-3-b}
Lorem ipsum
### Example Subsection 3 c {#example-subsection-3-c}
Lorem ipsum

View file

@ -0,0 +1,23 @@
---
id: introduction
title: Markdown Features introduction
sidebar_label: Introduction
description: Docusaurus uses GitHub Flavored Markdown (GFM). Find out more about Docusaurus-specific features when writing Markdown.
slug: /markdown-features
---
Documentation is one of your product's interfaces with your users. A well-written and well-organized set of docs helps your users understand your product quickly. Our aligned goal here is to help your users find and understand the information they need, as quickly as possible.
Docusaurus 2 uses modern tooling to help you compose your interactive documentations with ease. You may embed React components, or build live coding blocks where your users may play with the code on the spot. Start sharing your eureka moments with the code your audience cannot walk away from. It is perhaps the most effective way of attracting potential users.
In this section, we'd like to introduce you to the tools we've picked that we believe will help you build a powerful documentation. Let us walk you through with an example.
Markdown is a syntax that enables you to write formatted content in a readable syntax.
The [standard Markdown syntax](https://daringfireball.net/projects/markdown/syntax) is supported, and we use [MDX](https://mdxjs.com/) as the parsing engine, which can do much more than just parsing Markdown, like rendering React components inside your documents.
:::important
This section assumes you are using the official Docusaurus content plugins.
:::

View file

@ -0,0 +1,78 @@
---
id: plugins
title: Plugins
description: Using MDX plugins to expand Docusaurus Markdown functionalities
slug: /markdown-features/plugins
---
You can expand the MDX functionalities, using plugins.
Docusaurus content plugins support both [Remark](https://github.com/remarkjs/remark) and [Rehype](https://github.com/rehypejs/rehype) plugins that work with MDX.
## Configuring plugins {#configuring-plugins}
An MDX plugin is usually a npm package, so you install them like other npm packages using npm.
First, install your [Remark](https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins) and [Rehype](https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins) plugins.
For example:
```bash npm2yarn
npm install --save remark-images
npm install --save rehype-truncate
```
Next, import the plugins:
```js
const remarkImages = require('remark-images');
const rehypeTruncate = require('rehype-truncate');
```
Finally, add them to the `@docusaurus/preset-classic` options in `docusaurus.config.js`:
```js {10,11} title="docusaurus.config.js"
module.exports = {
// ...
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
// ...
remarkPlugins: [remarkImages],
rehypePlugins: [rehypeTruncate],
},
},
],
],
};
```
## Configuring plugin options {#configuring-plugin-options}
Some plugins can be configured and accept their own options. In that case, use the `[plugin, pluginOptions]` syntax, like so:
```jsx {10-13} title="docusaurus.config.js"
module.exports = {
// ...
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
// ...
remarkPlugins: [
plugin1,
[plugin2, {option1: {...}}],
],
},
},
],
],
};
```
See more information in the [MDX documentation](https://mdxjs.com/advanced/plugins).

View file

@ -0,0 +1,71 @@
---
id: react
title: Using React
description: Using the power of React in Docusaurus Markdown documents, thanks to MDX
slug: /markdown-features/react
---
import BrowserWindow from '@site/src/components/BrowserWindow';
Docusaurus has built-in support for [MDX](https://mdxjs.com/), which allows you to write JSX within your Markdown files and render them as React components.
:::note
While both `.md` and `.mdx` files are parsed using MDX, some of the syntax are treated slightly differently. For the most accurate parsing and better editor support, we recommend using the `.mdx` extension for files containing MDX syntax.
:::
Try this block here:
```jsx
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
I can write **Markdown** alongside my _JSX_!
```
Notice how it renders both the markup from your React component and the Markdown syntax:
```mdx-code-block
export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
<BrowserWindow minHeight={240} url="http://localhost:3000">
<Highlight color="#25c2a0">Docusaurus green</Highlight>
{` `}and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
I can write **Markdown** alongside my _JSX_!
</BrowserWindow>
```
<br />
You can also import your own components defined in other files or third-party components installed via npm! Check out the [MDX docs](https://mdxjs.com/) to see what other fancy stuff you can do with MDX.
:::caution
Since all doc files are parsed using MDX, any HTML is treated as JSX. Therefore, if you need to inline-style a component, follow JSX flavor and provide style objects. This behavior is different from Docusaurus 1. See also [Migrating from v1 to v2](../../migration/migration-manual.md#convert-style-attributes-to-style-objects-in-mdx).
:::

View file

@ -0,0 +1,228 @@
---
id: tabs
title: Tabs
description: Using tabs inside Docusaurus Markdown
slug: /markdown-features/tabs
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
To show tabbed content within Markdown files, you can fall back on MDX. Docusaurus provides `<Tabs>` components out-of-the-box.
```jsx
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs
defaultValue="apple"
values={[
{label: 'Apple', value: 'apple'},
{label: 'Orange', value: 'orange'},
{label: 'Banana', value: 'banana'},
]}>
<TabItem value="apple">This is an apple 🍎</TabItem>
<TabItem value="orange">This is an orange 🍊</TabItem>
<TabItem value="banana">This is a banana 🍌</TabItem>
</Tabs>;
```
And you will get the following:
```mdx-code-block
<Tabs
defaultValue="apple"
values={[
{label: 'Apple', value: 'apple'},
{label: 'Orange', value: 'orange'},
{label: 'Banana', value: 'banana'},
]}>
<TabItem value="apple">This is an apple 🍎</TabItem>
<TabItem value="orange">This is an orange 🍊</TabItem>
<TabItem value="banana">This is a banana 🍌</TabItem>
</Tabs>
```
:::info
By default, tabs are rendered eagerly, but it is possible to load them lazily by passing the `lazy` prop to the `Tabs` component.
:::
## Syncing tab choices {#syncing-tab-choices}
You may want choices of the same kind of tabs to sync with each other. For example, you might want to provide different instructions for users on Windows vs users on macOS, and you want to changing all OS-specific instructions tabs in one click. To achieve that, you can give all related tabs the same `groupId` prop. Note that doing this will persist the choice in `localStorage` and all `<Tab>` instances with the same `groupId` will update automatically when the value of one of them is changed. Note that `groupID` are globally-namespaced.
```jsx {2,14}
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]
}>
<TabItem value="win">Use Ctrl + C to copy.</TabItem>
<TabItem value="mac">Use Command + C to copy.</TabItem>
</Tabs>
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]
}>
<TabItem value="win">Use Ctrl + V to paste.</TabItem>
<TabItem value="mac">Use Command + V to paste.</TabItem>
</Tabs>
```
```mdx-code-block
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]}>
<TabItem value="win">Use Ctrl + C to copy.</TabItem>
<TabItem value="mac">Use Command + C to copy.</TabItem>
</Tabs>
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]}>
<TabItem value="win">Use Ctrl + V to paste.</TabItem>
<TabItem value="mac">Use Command + V to paste.</TabItem>
</Tabs>
```
For all tab groups that have the same `groupId`, the possible values do not need to be the same. If one tab group with chooses an value that does not exist in another tab group with the same `groupId`, the tab group with the missing value won't change its tab. You can see that from the following example. Try to select Linux, and the above tab groups doesn't change.
```jsx
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
{label: 'Linux', value: 'linux'},
]}>
<TabItem value="win">I am Windows.</TabItem>
<TabItem value="mac">I am macOS.</TabItem>
<TabItem value="linux">I am Linux.</TabItem>
</Tabs>
```
```mdx-code-block
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
{label: 'Linux', value: 'linux'},
]}>
<TabItem value="win">I am Windows.</TabItem>
<TabItem value="mac">I am macOS.</TabItem>
<TabItem value="linux">I am Linux.</TabItem>
</Tabs>
```
---
Tab choices with different `groupId`s will not interfere with each other:
```jsx {2,14}
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]
}>
<TabItem value="win">Windows in windows.</TabItem>
<TabItem value="mac">macOS is macOS.</TabItem>
</Tabs>
<Tabs
groupId="non-mac-operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'Unix', value: 'unix'},
]
}>
<TabItem value="win">Windows is windows.</TabItem>
<TabItem value="unix">Unix is unix.</TabItem>
</Tabs>
```
```mdx-code-block
<Tabs
groupId="operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'macOS', value: 'mac'},
]}>
<TabItem value="win">Windows in windows.</TabItem>
<TabItem value="mac">macOS is macOS.</TabItem>
</Tabs>
<Tabs
groupId="non-mac-operating-systems"
defaultValue="win"
values={[
{label: 'Windows', value: 'win'},
{label: 'Unix', value: 'unix'},
]}>
<TabItem value="win">Windows is windows.</TabItem>
<TabItem value="unix">Unix is unix.</TabItem>
</Tabs>
```
## Customizing tabs {#customizing-tabs}
You might want to customize the appearance of certain set of tabs. To do that you can pass the string in `className` prop and the specified CSS class will be added to the `Tabs` component:
```jsx {5}
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs
className="unique-tabs"
defaultValue="apple"
values={[
{label: 'Apple', value: 'apple'},
{label: 'Orange', value: 'orange'},
{label: 'Banana', value: 'banana'},
]}>
<TabItem value="apple">This is an apple 🍎</TabItem>
<TabItem value="orange">This is an orange 🍊</TabItem>
<TabItem value="banana">This is a banana 🍌</TabItem>
</Tabs>;
```
```mdx-code-block
<Tabs
className="unique-tabs"
defaultValue="apple"
values={[
{label: 'Apple', value: 'apple'},
{label: 'Orange', value: 'orange'},
{label: 'Banana', value: 'banana'},
]}>
<TabItem value="apple">This is an apple 🍎</TabItem>
<TabItem value="orange">This is an orange 🍊</TabItem>
<TabItem value="banana">This is a banana 🍌</TabItem>
</Tabs>
```