Aller au contenu principal
Version : 2.4.0

MDX et React

Using JSX in Markdown

Docusaurus has built-in support for MDX v1, which allows you to write JSX within your Markdown files and render them as React components.

remarque

While Docusaurus parses both .md and .mdx files using MDX, some of the syntaxes are treated slightly differently by third-party tools. For the most accurate parsing and better editor support, we recommend using the .mdx extension for files containing MDX syntax.

Check out the MDX docs to see what other fancy stuff you can do with 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_!

Remarquez comment il rend à la fois le balisage de votre composant React et la syntaxe Markdown :

http://localhost:3000
Docusaurus green and Facebook blue are my favorite colors.

I can write Markdown alongside my JSX!

MDX is JSX

Puisque tous les fichiers doc sont analysés en utilisant MDX, tout ce qui ressemble au HTML est en fait du JSX. Par conséquent, si vous devez donner un style en ligne à un composant, suivez le modèle JSX et fournissez des objets de style.

/* Instead of this: */
<span style="background-color: red">Foo</span>
/* Use this: */
<span style={{backgroundColor: 'red'}}>Foo</span>

Ce comportement est différent de Docusaurus 1. See also Migrating from v1 to v2.

In addition, MDX is not 100% compatible with CommonMark. Use the MDX playground to ensure that your syntax is valid MDX.

Importing components

Vous pouvez également importer vos propres composants définis dans d'autres fichiers ou composants tiers installés via 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';
astuce

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.

Si la déclaration de composants dans le format Markdown est très pratique pour les cas simples, elle devient difficile à maintenir en raison de la prise en charge limitée des éditeurs, des risques d'erreurs d'analyse et de la faible réutilisation. Use a separate .js file when your component involves complex JS logic:

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>
);
}
markdown-file.mdx
import Highlight from '@site/src/components/Highlight';

<Highlight color="#25c2a0">Docusaurus green</Highlight>
astuce

Si vous utilisez le même composant dans un grand nombre de fichiers, vous n'avez pas besoin de l'importer partout, pensez à l'ajouter à la portée globale. 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.

Par exemple, à partir de ce fichier 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. Puisque le CLI swizzle n'autorise pas encore l'enveloppe des fichiers non-composants, vous devriez créer manuellement l'enveloppe :

src/theme/MDXComponents.js
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!
http://localhost:3000

I can conveniently use Docusaurus green everywhere!

warning

We use upper-case tag names like Highlight on purpose.

A partir de MDX v2+ (Docusaurus v3+), les noms de balises minuscules sont toujours affichés en tant qu'éléments html natifs et n'utiliseront aucun mapping de composants que vous fournirez.

attention

This feature is powered by a wrapper provider. If you are importing Markdown in a React page, you have to supply this provider yourself through the MDXContent theme component.

src/pages/index.js
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 v2 utilise MDX v1, qui a beaucoup de cas connus où le contenu ne peut pas être correctement analysé comme du Markdown. Use the MDX playground to ensure that your syntax is valid MDX.

Samples of parsing failures

A paragraph starting with a JSX tag will be seen entirely as a JSX string:

<span style={{color: 'red'}}>Highlighted text</span> but afterwards _Markdown_ **doesn't work**
http://localhost:3000
Highlighted text but afterwards _Markdown_ **doesn't work**

Markdown within a JSX tag never works:

<span style={{color: 'red'}}>**Bold doesn't work**</span>
http://localhost:3000
**Bold doesn't work**

Text immediately below a JSX tag will be seen as JSX text:

<div style={{color: 'red'}}>
**Bold still doesn't work**
</div>
http://localhost:3000
**Bold still doesn't work**

Markdown text indented by four spaces will be seen as a code block:

<div style={{color: 'red'}}>

You may think I'm just some text...

</div>
http://localhost:3000
You may think I'm just some text...

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. In order to use raw-loader, you first need to install it in your project:

npm install --save raw-loader

Vous pouvez maintenant importer des extraits de code d'un autre fichier tel quel :

myMarkdownFile.mdx
import CodeBlock from '@theme/CodeBlock';
import MyComponentSource from '!!raw-loader!./myComponent';

<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>
http://localhost:3000
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import React, {useState} from 'react';

export default function MyComponent() {
const [bool, setBool] = useState(false);
return (
<div>
<p>MyComponent rendered !</p>
<p>bool={bool ? 'true' : 'false'}</p>
<p>
<button onClick={() => setBool((b) => !b)}>toggle bool</button>
</p>
</div>
);
}

See using code blocks in JSX for more details of the <CodeBlock> component.

remarque

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

Cette fonctionnalité est expérimentale et pourrait faire l'objet de modifications de l'API à l'avenir.

Importing Markdown

Vous pouvez utiliser des fichiers Markdown comme composants et les importer ailleurs, soit dans des fichiers Markdown, soit dans des pages React.

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.

_markdown-partial-example.mdx
<span>Hello {props.name}</span>

This is text some content from `_markdown-partial-example.mdx`.
someOtherDoc.mdx
import PartialExample from './_markdown-partial-example.mdx';

<PartialExample name="Sebastien" />
http://localhost:3000
Hello Sebastien

This is text some content from _markdown-partial-example.md.

De cette façon, vous pouvez réutiliser le contenu entre plusieurs pages et éviter de dupliquer le contenu.

attention

Actuellement, la table des matières ne contient pas les titres Markdown importés. This is a technical limitation that we are trying to solve (issue).

Available exports

Dans la page MDX, les variables suivantes sont disponibles en tant que variables globales :

  • 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 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).
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>
http://localhost:3000

The table of contents for this page, serialized:

[
{
"value": "Using JSX in Markdown",
"id": "using-jsx-in-markdown",
"level": 2
},
{
"value": "Exporting components",
"id": "exporting-components",
"level": 3
},
{
"value": "Importing components",
"id": "importing-components",
"level": 3
},
{
"value": "MDX component scope",
"id": "mdx-component-scope",
"level": 3
},
{
"value": "Markdown and JSX interoperability",
"id": "markdown-and-jsx-interoperability",
"level": 3
},
{
"value": "Importing code snippets",
"id": "importing-code-snippets",
"level": 2
},
{
"value": "Importing Markdown",
"id": "importing-markdown",
"level": 2
},
{
"value": "Available exports",
"id": "available-exports",
"level": 2
}
]

The front matter of this page:

  • id: react
  • description: Utiliser la puissance de React dans les documents Markdown de Docusaurus grâce à MDX
  • slug: /markdown-features/react

The title of this page is: MDX et React