MDX et React
Utilisation de JSX dans Markdown
Docusaurus a un support intégré pour MDX v1, ceci vous permet d'écrire du JSX dans vos fichiers Markdown et de les rendre sous forme de composants React.
Bien que Docusaurus analyse les fichiers .md
et .mdx
en utilisant MDX, certaines syntaxes sont traitées légèrement différemment par des outils tiers. Pour une analyse syntaxique plus précise et un meilleur support des éditeurs, nous recommandons d'utiliser l'extension .mdx
pour les fichiers contenant de la syntaxe MDX.
Consultez les docs MDX pour voir ce que vous pouvez faire avec MDX.
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 :
Je peux écrire en Markdown a côté de mon 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>
Ce comportement est différent de Docusaurus 1. Consulter aussi la Migration de v1 vers v2.
De plus, MDX n'est pas 100% compatible avec CommonMark. Utilisez le terrain de jeu de MDX pour vous assurer que votre syntaxe est un MDX valide.
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';
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 :
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 vert</Highlight>
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 :
- a
- liste !
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 :
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 v2+ 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 a wrapper provider. 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.
Interopérabilité de Markdown et JSX
Docusaurus v2 is using MDX v1, which has a lot of known cases where the content fails to be correctly parsed as Markdown. Utilisez le terrain de jeu de MDX pour vous assurer que votre syntaxe est un MDX valide.
Samples of parsing failures
A paragraph starting with a JSX tag will be seen entirely as a JSX string:
- Problem
- Workaround
<span style={{color: 'red'}}>Texte surligné</span> mais ensuite le _Markdown_ **ne fonctionne pas**
Utilisez JSX pour le reste de la ligne, ou préfixez la ligne avec du texte brut :
<span style={{color: 'red'}}>Utilisez JSX pour le paragraphe</span> pour <i>ne plus vous soucier</i> de <b>Markdown</b>
​<span style={{color: 'red'}}>← Il s'agit d'un espace de largeur zéro</span> et ensuite <i>Markdown</i> <b>fonctionne</b>
← Il s'agit d'un espace de largeur zéro et ensuite Markdown fonctionne
Le format Markdown dans une balise JSX ne fonctionne jamais :
- Problem
- Workaround
<span style={{color: 'red'}}>**La mise en gras ne fonctionne pas**</span>
Utilisez JSX à l'intérieur de la balise JSX, ou déplacez le Markdown vers la partie extérieure :
<span style={{color: 'red'}}><b>La mise en gras fonctionne maintenant</b></span>
**<span style={{color: 'red'}}>La mise en gras fonctionne maintenant</span>**
La mise en gras fonctionne maintenant
Le texte situé immédiatement sous une balise JSX sera considéré comme du texte JSX :
- Problem
- Workaround
<div style={{color: 'red'}}>
**La mise en gras ne fonctionne toujours pas**
</div>
Ajoutez une nouvelle ligne vide :
<div style={{color: 'red'}}>
**La mise en gras fonctionne maintenant**
</div>
La mise en gras fonctionne maintenant
Le texte Markdown indenté de quatre espaces sera considéré comme un bloc de code :
- Problem
- Workaround
<div style={{color: 'red'}}>
Vous pouvez croire que je suis juste un texte...
</div>
Vous pouvez croire que je suis juste un texte...
N'indentez pas :
<div style={{color: 'red'}}>
Maintenant, je suis vraiment juste un texte
</div>
Maintenant, je suis vraiment juste un texte
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
- Yarn
- pnpm
npm install --save raw-loader
yarn add raw-loader
pnpm add raw-loader
Now you can import code snippets from another file as it is:
import CodeBlock from '@theme/CodeBlock';
import MyComponentSource from '!!raw-loader!./myComponent';
<CodeBlock language="jsx">{MyComponentSource}</CodeBlock>
/**
* 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.
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.
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.
<span>Bonjour {props.name}</span>
Ceci est du texte du contenu de `_markdown-partial-example.mdx`.
import PartialExample from './_markdown-partial-example.mdx';
<PartialExample name="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.
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 frontmatter 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êteh1
dans le texte Markdown. Il estundefined
s'il n'y en a pas un (par exemple le titre spécifié dans le frontmatter).
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>
La table des matières pour cette page, sérialisé :
[
{
"value": "Utilisation de JSX dans Markdown",
"id": "using-jsx-in-markdown",
"level": 2
},
{
"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'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