mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-18 11:36:53 +02:00
chore: docs for Docusaurus 3.0.1 (#9597)
This commit is contained in:
parent
dc3584c2aa
commit
d59ea067ec
100 changed files with 40 additions and 1 deletions
|
@ -0,0 +1,373 @@
|
|||
---
|
||||
id: react
|
||||
description: Using the power of React in Docusaurus Markdown documents, thanks to MDX
|
||||
slug: /markdown-features/react
|
||||
---
|
||||
|
||||
# MDX and React
|
||||
|
||||
```mdx-code-block
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import styles from './markdown-features-react.module.css';
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Check out the [MDX docs](https://mdxjs.com/) to see what fancy stuff you can do with MDX.
|
||||
|
||||
:::tip Debugging MDX
|
||||
|
||||
The MDX format is quite strict, and you may get compilation errors.
|
||||
|
||||
Use the **[MDX playground](https://mdxjs.com/playground/)** to debug them and make sure your syntax is valid.
|
||||
|
||||
:::
|
||||
|
||||
### Exporting components {#exporting-components}
|
||||
|
||||
To define any custom component within an MDX file, you have to export it: only paragraphs that start with `export` will be parsed as components instead of prose.
|
||||
|
||||
```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}>
|
||||
|
||||
<><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>
|
||||
```
|
||||
|
||||
:::warning MDX is JSX
|
||||
|
||||
Since all doc files are parsed using MDX, anything that looks like HTML is actually JSX. Therefore, if you need to inline-style a component, follow JSX flavor and provide style objects.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```jsx
|
||||
/* Instead of this: */
|
||||
<span style="background-color: red">Foo</span>
|
||||
/* Use this: */
|
||||
<span style={{backgroundColor: 'red'}}>Foo</span>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Importing components {#importing-components}
|
||||
|
||||
You can also import your own components defined in other files or third-party components installed via npm.
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```md
|
||||
<!-- Docusaurus theme component -->
|
||||
import TOCInline from '@theme/TOCInline';
|
||||
<!-- External component -->
|
||||
import Button from '@mui/material/Button';
|
||||
<!-- Custom component -->
|
||||
import BrowserWindow from '@site/src/components/BrowserWindow';
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
The `@site` alias points to your website's directory, usually where the `docusaurus.config.js` file is. Using an alias instead of relative paths (`'../../src/components/BrowserWindow'`) saves you from updating import paths when moving files around, or when [versioning docs](../docs/versioning.mdx) and [translating](../../i18n/i18n-tutorial.mdx).
|
||||
|
||||
:::
|
||||
|
||||
While declaring components within Markdown is very convenient for simple cases, it becomes hard to maintain because of limited editor support, risks of parsing errors, and low reusability. Use a separate `.js` file when your component involves complex JS logic:
|
||||
|
||||
```jsx title="src/components/Highlight.js"
|
||||
import React from 'react';
|
||||
|
||||
export default function Highlight({children, color}) {
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
borderRadius: '2px',
|
||||
color: '#fff',
|
||||
padding: '0.2rem',
|
||||
}}>
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```md title="markdown-file.mdx"
|
||||
import Highlight from '@site/src/components/Highlight';
|
||||
|
||||
<Highlight color="#25c2a0">Docusaurus green</Highlight>
|
||||
```
|
||||
|
||||
:::tip
|
||||
|
||||
If you use the same component across a lot of files, you don't need to import it everywhere—consider adding it to the global scope. [See below](#mdx-component-scope)
|
||||
|
||||
:::
|
||||
|
||||
### MDX component scope {#mdx-component-scope}
|
||||
|
||||
Apart from [importing a component](#importing-components) and [exporting a component](#exporting-components), a third way to use a component in MDX is to **register it to the global scope**, which will make it automatically available in every MDX file, without any import statements.
|
||||
|
||||
For example, given this MDX file:
|
||||
|
||||
```md
|
||||
- a
|
||||
- list!
|
||||
|
||||
And some <Highlight>custom markup</Highlight>...
|
||||
```
|
||||
|
||||
It will be compiled to a React component containing `ul`, `li`, `p`, and `Highlight` elements. `Highlight` is not a native html element: you need to provide your own React component implementation for it.
|
||||
|
||||
In Docusaurus, the MDX component scope is provided by the `@theme/MDXComponents` file. It's not a React component, _per se_, unlike most other exports under the `@theme/` alias: it is a record from tag names like `Highlight` to their React component implementations.
|
||||
|
||||
If you [swizzle](../../swizzling.mdx) this component, you will find all tags that have been implemented, and you can further customize our implementation by swizzling the respective sub-component, like `@theme/MDXComponents/Code` (which is used to render [Markdown code blocks](./markdown-features-code-blocks.mdx)).
|
||||
|
||||
If you want to register extra tag names (like the `<Highlight>` tag above), you should consider [wrapping `@theme/MDXComponents`](../../swizzling.mdx#wrapping), so you don't have to maintain all the existing mappings. Since the swizzle CLI doesn't allow wrapping non-component files yet, you should manually create the wrapper:
|
||||
|
||||
```js title="src/theme/MDXComponents.js"
|
||||
import React from 'react';
|
||||
// Import the original mapper
|
||||
import MDXComponents from '@theme-original/MDXComponents';
|
||||
// highlight-next-line
|
||||
import Highlight from '@site/src/components/Highlight';
|
||||
|
||||
export default {
|
||||
// Re-use the default mapping
|
||||
...MDXComponents,
|
||||
// Map the "<Highlight>" tag to our Highlight component
|
||||
// `Highlight` will receive all props that were passed to `<Highlight>` in MDX
|
||||
// highlight-next-line
|
||||
Highlight,
|
||||
};
|
||||
```
|
||||
|
||||
And now, you can freely use `<Highlight>` in every page, without writing the import statement:
|
||||
|
||||
```md
|
||||
I can conveniently use <Highlight color="#25c2a0">Docusaurus green</Highlight> everywhere!
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
<BrowserWindow>
|
||||
|
||||
I can conveniently use <Highlight color="#25c2a0">Docusaurus green</Highlight> everywhere!
|
||||
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
We use **upper-case** tag names like `Highlight` on purpose.
|
||||
|
||||
From MDX v3+ onward (Docusaurus v3+), lower-case tag names are always rendered as native html elements, and will not use any component mapping you provide.
|
||||
|
||||
:::
|
||||
|
||||
:::warning
|
||||
|
||||
This feature is powered by [an `MDXProvider`](https://mdxjs.com/docs/using-mdx/#mdx-provider). If you are importing Markdown in a React page, you have to supply this provider yourself through the `MDXContent` theme component.
|
||||
|
||||
```jsx title="src/pages/index.js"
|
||||
import React from 'react';
|
||||
import FeatureDisplay from './_featureDisplay.mdx';
|
||||
// highlight-next-line
|
||||
import MDXContent from '@theme/MDXContent';
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div>
|
||||
{/* highlight-start */}
|
||||
<MDXContent>
|
||||
<FeatureDisplay />
|
||||
</MDXContent>
|
||||
{/* highlight-end */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
If you don't wrap your imported MDX with `MDXContent`, the global scope will not be available.
|
||||
|
||||
:::
|
||||
|
||||
### Markdown and JSX interoperability {#markdown-and-jsx-interoperability}
|
||||
|
||||
Docusaurus v3 is using [MDX v3](https://mdxjs.com/blog/v3/).
|
||||
|
||||
The [MDX syntax](https://mdxjs.com/docs/what-is-mdx/#mdx-syntax) is mostly compatible with [CommonMark](https://commonmark.org/), but is much stricter because your `.mdx` files can use JSX and are compiled into real React components (check the [playground](https://mdxjs.com/playground/)).
|
||||
|
||||
Some valid CommonMark features won't work with MDX ([more info](https://mdxjs.com/docs/what-is-mdx/#markdown)), notably:
|
||||
|
||||
- Indented code blocks: use triple backticks instead
|
||||
- Autolinks (`<http://localhost:3000>`): use regular link syntax instead (`[http://localhost:3000](http://localhost:3000)`)
|
||||
- HTML syntax (`<p style="color: red;">`): use JSX instead (`<p style={{color: 'red'}}>`)
|
||||
- Unescaped `{` and `<`: escape them with `\` instead (`\{` and `\<`)
|
||||
|
||||
:::danger Experimental CommonMark support
|
||||
|
||||
Docusaurus v3 makes it possible to opt-in for a less strict, standard [CommonMark](https://commonmark.org/) support with the following options:
|
||||
|
||||
- The `format: md` front matter
|
||||
- The `.md` file extension combined with the `siteConfig.markdown.format: "detect"` configuration
|
||||
|
||||
This feature is **experimental** and currently has a few [limitations](https://github.com/facebook/docusaurus/issues/9092).
|
||||
|
||||
:::
|
||||
|
||||
## Importing code snippets {#importing-code-snippets}
|
||||
|
||||
You can not only import a file containing a component definition, but also import any code file as raw text, and then insert it in a code block, thanks to [Webpack raw-loader](https://webpack.js.org/loaders/raw-loader/). In order to use `raw-loader`, you first need to install it in your project:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save raw-loader
|
||||
```
|
||||
|
||||
Now you can import code snippets from another file as it is:
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```jsx title="myMarkdownFile.mdx"
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import MyComponentSource from '!!raw-loader!./myComponent';
|
||||
|
||||
<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
import MyComponentSource from '!!raw-loader!@site/src/pages/examples/_myComponent';
|
||||
|
||||
<BrowserWindow>
|
||||
|
||||
<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>
|
||||
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
See [using code blocks in JSX](./markdown-features-code-blocks.mdx#usage-in-jsx) for more details of the `<CodeBlock>` component.
|
||||
|
||||
:::note
|
||||
|
||||
You have to use `<CodeBlock>` rather than the Markdown triple-backtick ` ``` `, because the latter will ship out any of its content as-is, but you want to interpolate the imported text here.
|
||||
|
||||
:::
|
||||
|
||||
:::warning
|
||||
|
||||
This feature is experimental and might be subject to breaking API changes in the future.
|
||||
|
||||
:::
|
||||
|
||||
## Importing Markdown {#importing-markdown}
|
||||
|
||||
You can use Markdown files as components and import them elsewhere, either in Markdown files or in React pages.
|
||||
|
||||
By convention, using the **`_` filename prefix** will not create any doc page and means the Markdown file is a **"partial"**, to be imported by other files.
|
||||
|
||||
```md title="_markdown-partial-example.mdx"
|
||||
<span>Hello {props.name}</span>
|
||||
|
||||
This is text some content from `_markdown-partial-example.mdx`.
|
||||
```
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```jsx title="someOtherDoc.mdx"
|
||||
import PartialExample from './_markdown-partial-example.mdx';
|
||||
|
||||
<PartialExample name="Sebastien" />
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
import PartialExample from './_markdown-partial-example.mdx';
|
||||
|
||||
<BrowserWindow>
|
||||
<PartialExample name="Sebastien" />
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
This way, you can reuse content among multiple pages and avoid duplicating materials.
|
||||
|
||||
:::warning
|
||||
|
||||
Currently, the table of contents does not contain the imported Markdown headings. This is a technical limitation that we are trying to solve ([issue](https://github.com/facebook/docusaurus/issues/3915)).
|
||||
|
||||
:::
|
||||
|
||||
## Available exports {#available-exports}
|
||||
|
||||
Within the MDX page, the following variables are available as globals:
|
||||
|
||||
- `frontMatter`: the front matter as a record of string keys and values;
|
||||
- `toc`: the table of contents, as a tree of headings. See also [Inline TOC](./markdown-features-toc.mdx#inline-table-of-contents) for a more concrete use-case.
|
||||
- `contentTitle`: the Markdown title, which is the first `h1` heading in the Markdown text. It's `undefined` if there isn't one (e.g. title specified in the front matter).
|
||||
|
||||
```jsx
|
||||
import TOCInline from '@theme/TOCInline';
|
||||
import CodeBlock from '@theme/CodeBlock';
|
||||
|
||||
The table of contents for this page, serialized:
|
||||
|
||||
<CodeBlock className="language-json">{JSON.stringify(toc, null, 2)}</CodeBlock>
|
||||
|
||||
The front matter of this page:
|
||||
|
||||
<ul>
|
||||
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
|
||||
</ul>
|
||||
|
||||
<p>The title of this page is: <b>{contentTitle}</b></p>
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
import TOCInline from '@theme/TOCInline';
|
||||
|
||||
<BrowserWindow>
|
||||
|
||||
The table of contents for this page, serialized:
|
||||
|
||||
<CodeBlock className="language-json">{JSON.stringify(toc, null, 2)}</CodeBlock>
|
||||
|
||||
The front matter of this page:
|
||||
|
||||
<ul>
|
||||
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
|
||||
</ul>
|
||||
|
||||
<p>The title of this page is: <b>{contentTitle}</b></p>
|
||||
|
||||
</BrowserWindow>
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue