MDX et React
Docusaurus has built-in support for MDX, which allows you to write JSX within your Markdown files and render them as React components.
Consultez les docs MDX pour voir ce que vous pouvez faire avec MDX.
Le format MDX est assez strict et vous risquez d'obtenir des erreurs de compilation.
Use the MDX playground to debug them and make sure your syntax is valid.
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 vert</Highlight> et <Highlight color="#1877F2">Facebook bleu</Highlight> sont mes couleurs préférées.
Je peux écrire du **Markdown** à côté de mon _JSX_ !
Remarquez comment il rend à la fois le balisage de votre composant React et la syntaxe Markdown :
Je peux écrire du Markdown à 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 cela : */
<span style="background-color: red">Foo</span>
/* Utilisez ceci : */
<span style={{backgroundColor: 'red'}}>Foo</span>
Importation des 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 :
- une
- liste !
Et quelques <Highlight>balisage personnalisé</Highlight>...
Il sera compilé à un composant React contenant des éléments 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 fichier @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 de composants React.
Si vous swizzlez ce composant, vous trouverez toutes les balises qui ont été 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 :
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 !
Je peux utiliser facilement Docusaurus vert partout !
Nous utilisons des noms de balises en majuscules comme Highlight
.
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
. Si vous importez Markdown dans une page React, vous devez fournir ce fournisseur vous-même via le composant de thème MDXContent
.
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 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:
- Blocs de code indentés : utiliser des triples backticks à la place
- 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.
Importation d'extraits de code
Vous pouvez non seulement importer un fichier contenant une définition de composant, mais aussi importer n'importe quel fichier de code sous forme de texte brut, puis l'insérer dans un bloc de code, grâce à Webpack raw-loader. Afin d'utiliser raw-loader
, vous devez d'abord l'installer dans votre projet :
- npm
- Yarn
- pnpm
npm install --save raw-loader
yarn add raw-loader
pnpm add raw-loader
Vous pouvez maintenant importer des extraits de code d'un autre fichier tel quel :
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>
);
}
Consultez l'utilisation de blocs de code en JSX pour plus de détails sur le composant <CodeBlock>
.
Vous devez utiliser <CodeBlock>
plutôt que le triple-backtick ```
, car ce dernier affichera tout son contenu tel quel, mais dans votre cas, vous voulez interpoler le texte importé ici.
Cette fonctionnalité est expérimentale et pourrait faire l'objet de modifications de l'API à l'avenir.
Importation de Markdown
Vous pouvez utiliser des fichiers Markdown comme composants et les importer ailleurs, soit dans des fichiers Markdown, soit dans des pages React.
Par convention, l'utilisation du _
pour le préfixe du nom de fichier ne créera aucune page doc et signifie que le fichier Markdown est un « partiel », à importer par d'autres fichiers.
<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
.
De cette façon, vous pouvez réutiliser le contenu entre plusieurs pages et éviter de dupliquer le contenu.
Actuellement, la table des matières ne contient pas les titres Markdown importés. Il s'agit d'une limitation technique que nous essayons de résoudre (issue).
Exportations disponibles
Dans la page MDX, les variables suivantes sont disponibles en tant que variables globales :
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êteh1
dans le texte Markdown. Il estundefined
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>
La table des matières pour cette page, sérialisé :
[
{
"value": "Exportation des composants",
"id": "exporting-components",
"level": 3
},
{
"value": "Importation des 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