mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 10:17:55 +02:00
218 lines
6.4 KiB
Text
218 lines
6.4 KiB
Text
---
|
|
id: react
|
|
title: MDX and 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';
|
|
```
|
|
|
|
## Using JSX in Markdown {#using-jsx-in-markdown}
|
|
|
|
Docusaurus has built-in support for [MDX v1](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.
|
|
|
|
:::
|
|
|
|
:::caution
|
|
|
|
MDX is not [100% compatible with CommonMark](https://github.com/facebook/docusaurus/issues/3018).
|
|
|
|
Use the **[MDX playground](https://mdx-git-renovate-babel-monorepo-mdx.vercel.app/playground)** to ensure that your syntax is valid MDX.
|
|
|
|
:::
|
|
|
|
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).
|
|
|
|
:::
|
|
|
|
## 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`, first you 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-start -->
|
|
```jsx title="myMarkdownFile.mdx"
|
|
import CodeBlock from '@theme/CodeBlock';
|
|
import MyComponentSource from '!!raw-loader!./myComponent';
|
|
|
|
<CodeBlock className="language-jsx">{MyComponentSource}</CodeBlock>
|
|
```
|
|
<!-- prettier-ignore-end -->
|
|
|
|
```mdx-code-block
|
|
import CodeBlock from '@theme/CodeBlock';
|
|
import MyComponentSource from '!!raw-loader!@site/src/pages/examples/_myComponent';
|
|
|
|
<BrowserWindow url="http://localhost:3000">
|
|
|
|
<CodeBlock className="language-jsx">{MyComponentSource}</CodeBlock>
|
|
|
|
</BrowserWindow>
|
|
|
|
<br />
|
|
```
|
|
|
|
You can also pass `title` prop to `CodeBlock` component in order to appear it as header above your codeblock:
|
|
|
|
```jsx
|
|
<CodeBlock className="language-jsx" title="/src/myComponent">
|
|
{MyComponentSource}
|
|
</CodeBlock>
|
|
```
|
|
|
|
:::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 JSX to insert the imported text here.
|
|
|
|
:::
|
|
|
|
:::warning
|
|
|
|
This feature is experimental and might be subject to API breaking 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`.
|
|
```
|
|
|
|
```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 url="http://localhost:3000">
|
|
<PartialExample name="Sebastien" />
|
|
</BrowserWindow>
|
|
|
|
<br />
|
|
```
|
|
|
|
This way, you can reuse contents among multiple pages and avoid duplicating materials.
|
|
|
|
:::caution
|
|
|
|
The table-of-contents does not currently 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
|
|
|
|
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-inline-toc.mdx) 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>
|
|
```
|