Aller au contenu principal
Version : Canary 🚧

MDX et React

Docusaurus a un support intégré pour MDX v2, ceci vous permet d'écrire du JSX dans vos fichiers Markdown et de les rendre sous forme de composants React.

Consultez les docs MDX pour voir ce que vous pouvez faire avec MDX.

Débogage MDX

Le format MDX est assez strict et vous risquez d'obtenir des erreurs de compilation.

Utilisez le terrain de jeu MDX pour les déboguer et vous assurer que votre syntaxe est valide.

Exportation des composants

Pour définir un composant personnalisé dans un fichier MDX, vous devez l'exporter : seuls les paragraphes qui commencent par export seront analysés comme des composants au lieu de prose.

export const Highlight = ({children, color}) => (
<span
style={{
backgroundColor: color,
borderRadius: '2px',
color: '#fff',
padding: '0.2rem',
}}>
{children}
</span>
);

<Highlight color="#25c2a0">Docusaurus en vert</Highlight> et <Highlight color="#1877F2">Facebook en bleu</Highlight> sont mes couleurs préférées.

Je peux écrire en **Markdown** a côté de mon _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.

Je peux écrire du Markdown à côté de mon JSX !

MDX est 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.

/* Au lieu de ceci : */
<span style="background-color: red">Foo</span>
/* Utilisez ceci : */
<span style={{backgroundColor: 'red'}}>Foo</span>

Importation de composants

Vous pouvez également importer vos propres composants définis dans d'autres fichiers ou composants tiers installés via npm.

<!-- Composant du thème Docusaurus -->
import TOCInline from '@theme/TOCInline';
<!-- Composant externe -->
import Button from '@mui/material/Button';
<!-- Composant personnalisé -->
import BrowserWindow from '@site/src/components/BrowserWindow';
astuce

L'alias @site pointe vers le répertoire de votre site web, habituellement où se trouve le fichier docusaurus.config.js. L'utilisation d'un alias au lieu des chemins relatifs ('../.. src/components/BrowserWindow') vous évite de mettre à jour les chemins d'importation lors du déplacement des fichiers, de la documentation versionnée et de la traduction.

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. Utilisez un fichier .js séparé lorsque votre composant implique une logique JavaScript complexe :

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 vert</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. Voir ci-dessous

Portée des composants MDX

En plus de l'importation d'un composant et l'exportation d'un composant, une troisième façon d'utiliser un composant dans MDX est de l'enregistrer dans la portée globale, qui le rendra automatiquement disponible dans tous les fichiers MDX, sans aucune instruction d'importation.

Par exemple, à partir de ce fichier MDX :

- une
- liste !

Et quelques <Highlight>balises personnalisées</Highlight>...

Il sera compilé en un composant React contenant les balises ul, li, p et Highlight. Highlight n'est pas un élément html natif : vous devez fournir votre propre implémentation de composants React pour lui.

Dans Docusaurus, la portée du composant MDX est fournie par le composant @theme/MDXComponents. Ce n'est pas un composant React, en soi, contrairement à la plupart des autres exportations sous l'alias @theme/ : c'est un enregistrement de noms de balises comme Highlight vers leurs implémentations personnalisées.

Si vous swizzlez ce composant, vous trouverez toutes les balises qui ont été réimplémentées, et vous pouvez personnaliser davantage notre implémentation en swizzlant les sous-composants respectifs, comme @theme/MDXComponents/Code (qui est utilisé pour implémenter la fonctionnalité Blocs de code Markdown).

Si vous souhaitez enregistrer des noms de balises supplémentaires (comme la balise <Highlight> ci-dessus), vous devez envisager d'envelopper @theme/MDXComponents, afin de ne pas avoir à maintenir tous les correspondances existantes. 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';
// Importe le mapper original
import MDXComponents from '@theme-original/MDXComponents';
import Highlight from '@site/src/components/Highlight';

export default {
// Réutilise la correspondance par défaut
...MDXComponents,
// Ajoute la balise "highlight" à notre composant <Highlight> };
// `Highlight` recevra tous les props qui ont été passés à `<Highlight>` dans MDX
Highlight,
};

Et maintenant, vous pouvez librement utiliser <Highlight> dans chaque page, sans écrire l'instruction d'importation :

Je peux facilement utiliser <Highlight color="#25c2a0">Docusaurus vert</Highlight> partout !
http://localhost:3000

Je peux utiliser facilement Docusaurus vert partout !

attention

Nous utilisons des noms de balises en majuscules comme Highlight.

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

Cette fonctionnalité est propulsée par un MDXProvider. Si vous importez Markdown dans une page React, vous devez fournir ce fournisseur vous-même via le composant de thème MDXContent.

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>
);
}

Si vous n'enveloppez pas votre MDX importé avec MDXContent, la portée globale ne sera pas disponible.

Interopérabilité de Markdown et JSX

Docusaurus v3 utilise MDX v2.

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).

Certaines fonctionnalités valides de CommonMark ne fonctionneront pas avec MDX (plus d'infos), notamment :

  • Blocs de code indentés : utiliser des triples backticks à la place
  • Auto-Liens (<http://localhost:3000>) : utiliser la syntaxe des liens habituels à la place ([http://localhost:3000](http://localhost:3000))
  • Syntaxe HTML (<p style="color: red;">) : utilisez JSX à la place (<p style={{color: 'red'}}>)
  • { et < non-échappés : échappez-les avec \ à la place (\{ et \<)
Experimental CommonMark support

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 the siteConfig.markdown.format: "detect" configuration

This feature is experimental and currently has a few limitations.

Importation d'extraits de code

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

Now you can import code snippets from another file as it is:

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.

attention

This feature is experimental and might be subject to breaking API changes in the future.

Importation de 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.

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

Ceci est du texte du contenu de `_markdown-partial-example.mdx`.
someOtherDoc.mdx
import PartialExample from './_markdown-partial-example.mdx';

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

Ceci est du texte du contenu de _markdown-partial-example.md.

This way, you can reuse content among multiple pages and avoid duplicating materials.

attention

Currently, the table of contents does not contain the imported Markdown headings. This is a technical limitation that we are trying to solve (issue).

Exportations disponibles

Within the MDX page, the following variables are available as globals:

  • frontMatter : le front matter sous forme d'un enregistrement de clés et de valeurs de type chaîne;
  • toc : la table des matières, comme un arbre d'entêtes. Consultez aussi Table des matières en ligne pour un cas d'utilisation plus concret.
  • contentTitle : le titre Markdown, qui est la première entête h1 dans le texte Markdown. Il est undefined s'il n'y en a pas un (par exemple le titre spécifié dans le front matter).
import TOCInline from '@theme/TOCInline';
import CodeBlock from '@theme/CodeBlock';

La table des matières pour cette page, sérialisé :

<CodeBlock className="language-json">{JSON.stringify(toc, null, 2)}</CodeBlock>

Le frontmatter de cette page :

<ul>
{Object.entries(frontMatter).map(([key, value]) => <li key={key}><b>{key}</b>: {value}</li>)}
</ul>

<p>Le titre de cette page est : <b>{contentTitle}</b></p>
http://localhost:3000

La table des matières pour cette page, sérialisé :

[
{
"value": "Exportation des composants",
"id": "exporting-components",
"level": 3
},
{
"value": "Importation de composants",
"id": "importing-components",
"level": 3
},
{
"value": "Portée des composants MDX",
"id": "mdx-component-scope",
"level": 3
},
{
"value": "Interopérabilité de Markdown et JSX",
"id": "markdown-and-jsx-interoperability",
"level": 3
},
{
"value": "Importation d&#39;extraits de code",
"id": "importing-code-snippets",
"level": 2
},
{
"value": "Importation de Markdown",
"id": "importing-markdown",
"level": 2
},
{
"value": "Exportations disponibles",
"id": "available-exports",
"level": 2
}
]

Le frontmatter de cette page :

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

Le titre de cette page est : MDX et React