MDX 和 React
Docusaurus has built-in support for MDX, which allows you to write JSX within your Markdown files and render them as React components.
Check out the MDX docs to see what fancy stuff you can do with MDX.
MDX格式是相当严格的,您可能会遇到编译错误。
Use the MDX playground to debug them and make sure your syntax is valid.
Prettier, the most popular formatter, supports only the legacy MDX v1. If you get an unintentional formatting result, you may want to add {/* prettier-ignore */}
before the problematic area, or add *.mdx
to your .prettierignore
, until Prettier has proper support for MDX v3. One of the main authors of MDX recommends remark-cli
with remark-mdx
.
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.
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_!
注意它是怎么同时渲染 React 组件和 Markdown 语法的:
I can write Markdown alongside my JSX!
由于所有文档文件都是使用MDX解析的,任何看起来像HTML的内容实际上是JSX语法。 因此,如果您需要对组件进行内联样式处理,请遵循JSX风格,并提供样式对象。
/* Instead of this: */
<span style="background-color: red">Foo</span>
/* Use this: */
<span style={{backgroundColor: 'red'}}>Foo</span>
Importing components
您还可以导入其他文件中定义的自己的组件或通过npm安装的第三方组件。
<!-- 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';
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 and translating.
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:
import React from 'react';
export default function Highlight({children, color}) {
return (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);
}
import Highlight from '@site/src/components/Highlight';
<Highlight color="#25c2a0">Docusaurus green</Highlight>
如果你在许多文件中都用到了同一个组件,你不需要每一次都导入它——你可以考虑把它添加到全局范围导入。 See below
MDX component scope
Apart from importing a component and exporting a component, 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.
例如,在下面给定的 MDX 文件中:
- 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 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).
If you want to register extra tag names (like the <Highlight>
tag above), you should consider wrapping @theme/MDXComponents
, 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:
import React from 'react';
// Import the original mapper
import MDXComponents from '@theme-original/MDXComponents';
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,
};
And now, you can freely use <Highlight>
in every page, without writing the import statement:
I can conveniently use <Highlight color="#25c2a0">Docusaurus green</Highlight> everywhere!
I can conveniently use Docusaurus green everywhere!
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.
This feature is powered by an MDXProvider
. If you are importing Markdown in a React page, you have to supply this provider yourself through the MDXContent
theme component.
import React from 'react';
import FeatureDisplay from './_featureDisplay.mdx';
import MDXContent from '@theme/MDXContent';
export default function LandingPage() {
return (
<div>
<MDXContent>
<FeatureDisplay />
</MDXContent>
</div>
);
}
If you don't wrap your imported MDX with MDXContent
, the global scope will not be available.
Markdown and JSX interoperability
Docusaurus v3 is using MDX v3.
The MDX syntax is mostly compatible with CommonMark, but is much stricter because your .mdx
files can use JSX and are compiled into real React components (check the playground).
Some valid CommonMark features won't work with MDX (more info), 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\<
)
Docusaurus v3 makes it possible to opt-in for a less strict, standard CommonMark support with the following options:
- The
format: md
front matter - The
.md
file extension combined with thesiteConfig.markdown.format: "detect"
configuration
This feature is experimental and currently has a few limitations.