Aller au contenu

@astrojs/ markdoc

Cette intégration Astro permet d’utiliser Markdoc pour créer des composants, des pages et des entrées de collection de contenu.

Markdoc vous permet d’améliorer votre Markdown avec des composants Astro. Si vous avez du contenu existant rédigé dans Markdoc, cette intégration vous permet d’apporter ces fichiers à votre projet Astro en utilisant des collections de contenu.

Astro inclut une commande astro add pour automatiser l’installation des intégrations officielles. Si vous préférez, vous pouvez installer les intégrations manuellement à la place.

Exécutez l’une des commandes suivantes dans une nouvelle fenêtre de terminal.

Fenêtre de terminal
npx astro add markdoc

Si vous rencontrez des problèmes, n’hésitez pas à nous les signaler sur GitHub et essayez les étapes d’installation manuelle ci-dessous.

Tout d’abord, installez le paquet @astrojs/markdoc :

Fenêtre de terminal
npm install @astrojs/markdoc

Ensuite, appliquez l’intégration à votre fichier astro.config.* en utilisant la propriété integrations :

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc()],
});

VS Code supporte Markdown par défaut. Cependant, pour le support de l’éditeur Markdoc, vous pouvez ajouter le paramètre suivant dans la configuration de VSCode. Cela permet de s’assurer que la création de fichiers Markdoc offre une expérience d’édition similaire à celle de Markdown.

.vscode/settings.json
{
"files.associations": {
"*.mdoc": "markdown"
}
}

Les fichiers Markdoc ne peuvent être utilisés que dans les collections de contenus. Ajoutez des entrées à n’importe quelle collection de contenus en utilisant l’extension .mdoc :

  • Répertoiresrc/
  • Répertoirecontent/
  • Répertoiredocs/
  • why-markdoc.mdoc
  • quick-start.mdoc

Interrogez ensuite votre collection à l’aide des API de Collections de contenus :

src/pages/why-markdoc.astro
---
import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<!--Accéder aux propriétés du Frontmatter avec `data`-->
<h1>{entry.data.title}</h1>
<!--Rendre le contenu d'un Markdoc avec le composant Content-->
<Content />
Voir les docs de la collection de contenus Astro pour plus d’informations.

@astrojs/markdoc offre des options de configuration pour utiliser toutes les fonctionnalités de Markdoc et connecter des composants d’interface utilisateur à votre contenu.

Utiliser les composants Astro comme balises Markdoc

Titre de la section Utiliser les composants Astro comme balises Markdoc

Vous pouvez configurer des Markdoc tags qui correspondent à des composants .astro. Vous pouvez ajouter une nouvelle balise en créant un fichier markdoc.config.mjs|ts à la racine de votre projet et en configurant l’attribut tag.

Cet exemple rend un composant Aside, et permet de passer une propriété type sous forme de chaîne de caractères :

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
aside: {
render: component('./src/components/Aside.astro'),
attributes: {
// Markdoc exige des définitions de type pour chaque attribut.
// Ceux-ci doivent refléter le type `Props` du composant
// que vous rendez.
// Voir la documentation de Markdoc sur la définition des attributs.
// https://markdoc.dev/docs/attributes#defining-attributes
type: { type: String },
},
},
},
});

Ce composant peut maintenant être utilisé dans vos fichiers Markdoc avec la balise {% aside %}. Les enfants seront transmis au slot par défaut de votre composant :

# Bienvenue sur Markdoc 👋
{% aside type="tip" %}
Utilisez des balises comme cette fantaisie "aside" pour ajouter un peu de _flair_ à vos documents.
{% /aside %}

Utiliser des composants Astro à partir de paquets npm et de fichiers TypeScript.

Titre de la section Utiliser des composants Astro à partir de paquets npm et de fichiers TypeScript.

Vous pouvez avoir besoin d’utiliser des composants Astro exposés en tant qu’exportations nommées à partir de fichiers TypeScript ou JavaScript. Cela est fréquent lors de l’utilisation de paquets npm et de systèmes de conception.

Vous pouvez passer le nom de l’importation comme second argument à la fonction component() :

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
tabs: {
render: component('@astrojs/starlight/components', 'Tabs'),
},
},
});

Cela génère la déclaration d’importation suivante en interne :

import { Tabs } from '@astrojs/starlight/components';

@astrojs/markdoc ajoute automatiquement des liens d’ancrage à vos titres, et génère une liste de titres via l’API des Collections de contenu. Pour personnaliser davantage le rendu des titres, vous pouvez appliquer un composant Astro en tant que nœud Markdoc.

Cet exemple rend un composant Heading.astro en utilisant la propriété render :

markdoc.config.mjs
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
heading: {
...nodes.heading, // Conserve la génération des liens d'ancrage par défaut
render: component('./src/components/Heading.astro'),
},
},
});

Tous les titres Markdown rendront le composant Heading.astro et passeront les attributs suivants en tant qu’accessoires du composant :

  • level : number Le niveau de la rubrique 1 - 6
  • id : string Un id généré à partir du contenu textuel de la rubrique. Cela correspond au slug généré par la fonction content render().

Par exemple, le titre ### Level 3 heading! passera level : 3 et id : 'level-3-heading' en tant qu’éléments du composant.

Mise en valeur de la syntaxe (highlighting)

Titre de la section Mise en valeur de la syntaxe (highlighting)

@astrojs/markdoc fournit les extensions Shiki et Prism pour mettre en évidence vos blocs de code.

Appliquez l’extension shiki() à votre configuration Markdoc en utilisant la propriété extends. Vous pouvez optionnellement passer un objet de configuration shiki :

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import shiki from '@astrojs/markdoc/shiki';
export default defineMarkdocConfig({
extends: [
shiki({
// Choisissez parmi les thèmes intégrés de Shiki (ou ajoutez les vôtres)
// Défaut : 'github-dark'
// https://github.com/shikijs/shiki/blob/main/docs/themes.md
theme: 'dracula',
// Activer l'habillage des mots pour éviter le défilement horizontal
// Défaut : false
wrap: true,
// Passer des langues personnalisées
// Note : Shiki a d'innombrables langages intégrés, y compris `.astro` !
// https://github.com/shikijs/shiki/blob/main/docs/languages.md
langs: [],
}),
],
});

Appliquez l’extension prism() à votre configuration Markdoc en utilisant la propriété extends.

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import prism from '@astrojs/markdoc/prism';
export default defineMarkdocConfig({
extends: [prism()],
});
Pour en savoir plus sur la configuration des feuilles de style Prism, voir notre guide sur la coloration syntaxique.

Markdoc entoure les documents d’une balise <article> par défaut. Ceci peut être changé à partir du nœud Markdoc document. Ceci accepte un nom d’élément HTML ou null si vous préférez supprimer l’élément enveloppant :

markdoc.config.mjs
import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
document: {
...nodes.document, // Appliquer les valeurs par défaut pour les autres options
render: null, // par défaut "article"
},
},
});

Nœuds / éléments Markdoc personnalisés

Titre de la section Nœuds / éléments Markdoc personnalisés

Il se peut que vous souhaitiez rendre les éléments Markdown standard, tels que les paragraphes et le texte en gras, sous forme de composants Astro. Pour cela, vous pouvez configurer un nœud Markdoc. Si un nœud donné reçoit des attributs, ceux-ci seront disponibles en tant qu’accessoires du composant.

Cet exemple rend les guillemets avec un composant personnalisé Quote.astro :

markdoc.config.mjs
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
nodes: {
blockquote: {
...nodes.blockquote, // Appliquer les valeurs par défaut de Markdoc pour les autres options
render: component('./src/components/Quote.astro'),
},
},
});

Composants d’image personnalisés dans Markdoc

Titre de la section Composants d’image personnalisés dans Markdoc

Le composant <Image /> d’Astro ne peut pas être utilisé directement dans Markdoc. Cependant, vous pouvez configurer un composant Astro pour remplacer le nœud d’image par défaut chaque fois que la syntaxe d’image native ![]() est utilisée, ou en tant que balise Markdoc personnalisée pour vous permettre de spécifier des attributs d’image supplémentaires.

Remplacer le lien d’image par défaut de Markdoc

Titre de la section Remplacer le lien d’image par défaut de Markdoc

Pour remplacer le lien d’image par défaut, vous pouvez configurer un composant .astro qui sera rendu à la place d’un <img> standard.

  1. Créez un composant MarkdocImage.astro personnalisé pour passer les propriétés src et alt de votre image au composant <Image /> :

    src/components/MarkdocImage.astro
    ---
    import { Image } from "astro:assets";
    interface Props {
    src: ImageMetadata;
    alt: string;
    }
    const { src, alt } = Astro.props;
    ---
    <Image src={src} alt={alt} />
  2. Le composant <Image /> nécessite une width et height pour les images distantes, qui ne peuvent pas être fournies par la syntaxe ![](). Pour éviter les erreurs lors de l’utilisation d’images distantes, mettez à jour votre composant <img> pour qu’il rende une image HTML standard lorsqu’une URL distante src est trouvée :

    src/components/MarkdocImage.astro
    ---
    import { Image } from "astro:assets";
    interface Props {
    src: ImageMetadata | string;
    alt: string;
    }
    const { src, alt } = Astro.props;
    ---
    <Image src={src} alt={alt} />
    {
    typeof src === 'string' ? <img src={src} alt={alt} /> : <Image src={src} alt={alt} />
    }
  3. Configurez Markdoc pour qu’il remplace le lien d’image par défaut et rende MarkdocImage.astro :

    markdoc.config.mjs
    import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
    export default defineMarkdocConfig({
    nodes: {
    image: {
    ...nodes.image, // Applique les valeurs par défaut de Markdoc pour les autres options
    render: component('./src/components/MarkdocImage.astro'),
    },
    },
    });
  4. La syntaxe de l’image native dans n’importe quel fichier .mdoc utilisera désormais le composant <Image /> pour optimiser vos images locales. Les images distantes peuvent toujours être utilisées, mais ne seront pas rendues par le composant <Image /> d’Astro.

    src/content/blog/post.mdoc
    <!-- Optimisé par <Image /> -->
    ![Une photo d'un chat](/chat.jpg)
    <!-- Non optimisé <img> -->
    ![Une photo d'un chien](https://exemple.com/chien.jpg)

Créer une balise d’image Markdoc personnalisée

Titre de la section Créer une balise d’image Markdoc personnalisée

Une balise Markdoc image vous permet de définir des attributs supplémentaires sur votre image qui ne sont pas possibles avec la syntaxe ![](). Par exemple, les balises d’images personnalisées vous permettent d’utiliser le composant <Image /> d’Astro pour les images distantes qui nécessitent une width et height.

Les étapes suivantes permettront de créer une balise image Markdoc personnalisée pour afficher un élément <figure> avec une légende, en utilisant le composant <Image /> d’Astro pour optimiser l’image.

  1. Créez un composant MarkdocFigure.astro pour recevoir les props nécessaires et rendre une image avec une légende :

    src/components/MarkdocFigure.astro
    ---
    // src/components/MarkdocFigure.astro
    import { Image } from "astro:assets";
    interface Props {
    src: ImageMetadata | string;
    alt: string;
    width: number;
    height: number;
    caption: string;
    }
    const { src, alt, width, height, caption } = Astro.props;
    ---
    <figure>
    <Image {src} {alt} {width} {height} />
    {caption && <figcaption>{caption}</figcaption>}
    </figure>
  2. Configurez votre balise d’image personnalisée pour rendre votre composant Astro :

    markdoc.config.mjs
    import { component, defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
    export default defineMarkdocConfig({
    tags: {
    image: {
    attributes: nodes.image.attributes,
    render: component('./src/components/MarkdocFigure.astro'),
    },
    },
    });
  3. Utilisez la balise image dans les fichiers Markdoc pour afficher une figure avec légende, en fournissant tous les props nécessaires à votre composant :

    {% image src="./astro-logo.png" alt="Logo Astro" width="100" height="100" caption="une légende !" %}

    Utiliser des composants d’interface utilisateur côté client

    Titre de la section Utiliser des composants d’interface utilisateur côté client

    Les balises et les nœuds sont limités aux fichiers .astro. Pour intégrer des composants d’interface utilisateur côté client dans Markdoc, utilisez un composant .astro enveloppant qui rend un composant de framework avec la directive client: de votre choix.

    Cet exemple englobe un composant React Aside.tsx avec un composant ClientAside.astro :

    src/components/ClientAside.astro
    ---
    import Aside from './Aside';
    ---
    <Aside {...Astro.props} client:load />

Ce composant Astro peut maintenant être passé à la propriété render pour n’importe quel tag ou node dans votre configuration :

markdoc.config.mjs
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
tags: {
aside: {
render: component('./src/components/ClientAside.astro'),
attributes: {
type: { type: String },
},
},
},
});

Le fichier markdoc.config.mjs|ts accepte toutes les options de configuration de Markdoc, y compris les tags et les fonctions.

Vous pouvez passer ces options à partir de l’exportation par défaut dans votre fichier markdoc.config.mjs|ts :

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
functions: {
getCountryEmoji: {
transform(parameters) {
const [country] = Object.values(parameters);
const countryToEmojiMap = {
japan: '🇯🇵',
spain: '🇪🇸',
france: '🇫🇷',
};
return countryToEmojiMap[country] ?? '🏳';
},
},
},
});

Vous pouvez désormais appeler cette fonction à partir de n’importe quelle entrée de contenu Markdoc :

¡Hola {% getCountryEmoji("spain") %}!
Voir la documentation Markdoc pour plus d’informations sur l’utilisation de variables ou de fonctions dans votre contenu.

Si vous utilisez VS Code, il existe une extension de langage Markdoc officielle qui inclut la coloration syntaxique et l’autocomplétion pour les balises configurées. Voir le serveur de langue sur GitHub pour plus d’informations.

Pour configurer l’extension, créez un fichier markdoc.config.json à la racine du projet avec le contenu suivant :

markdoc.config.json
[
{
"id": "my-site",
"path": "src/content",
"schema": {
"path": "markdoc.config.mjs",
"type": "esm",
"property": "default",
"watch": true
}
}
]

La propriété schema contient toutes les informations permettant de configurer le serveur de langues pour les collections de contenus Astro. Elle accepte les propriétés suivantes :

  • path : Le chemin vers le fichier de configuration.
  • type : Le type de module que votre fichier de configuration utilise (esm permet la syntaxe import).
  • property : Le nom de la propriété exportée qui contient l’objet de configuration.
  • watch : Indique au serveur de surveiller les changements dans la configuration.

La propriété de premier niveau path indique au serveur où se trouve le contenu. Comme Markdoc est spécifique aux collections de contenu, vous pouvez utiliser src/content.

Vous pouvez avoir besoin de passer des variables à votre contenu. Ceci est utile pour passer des paramètres SSR comme les tests A/B.

Les variables peuvent être passées en tant que props via le composant Content :

src/pages/why-markdoc.astro
---
import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<!--Passe le paramètre `abTest` comme variable-->
<Content abTestGroup={Astro.params.abTestGroup} />

Maintenant, abTestGroup est disponible comme variable dans docs/why-markdoc.mdoc :

src/content/docs/why-markdoc.mdoc
{% if $abTestGroup === 'image-optimization-lover' %}
Laissez-moi vous parler de l'optimisation des images...
{% /if %}

Pour rendre une variable globale à tous les fichiers Markdoc, vous pouvez utiliser l’attribut variables de votre markdoc.config.mjs|ts :

markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({
variables: {
environment: process.env.IS_PROD ? 'prod' : 'dev',
},
});

Accéder au Frontmatter à partir de votre contenu Markdoc

Titre de la section Accéder au Frontmatter à partir de votre contenu Markdoc

Pour accéder au frontmatter, vous pouvez passer la propriété de l’entrée data en tant que variable à l’endroit où vous rendez votre contenu :

src/pages/why-markdoc.astro
---
import { getEntry } from 'astro:content';
const entry = await getEntry('docs', 'why-markdoc');
const { Content } = await entry.render();
---
<Content frontmatter={entry.data} />

Vous pouvez maintenant y accéder en tant que $frontmatter dans votre Markdoc.

Options de configuration de l’intégration

Titre de la section Options de configuration de l’intégration

L’intégration Astro Markdoc gère la configuration des options et des capacités de Markdoc qui ne sont pas disponibles dans le fichier markdoc.config.js.

Permet d’écrire des balises HTML à côté des balises et des nœuds Markdoc.

Par défaut, Markdoc ne reconnaît pas les balises HTML comme du contenu sémantique.

Pour obtenir une expérience plus proche de Markdoc, où les éléments HTML peuvent être inclus avec votre contenu, mettez allowHTML:true comme option d’intégration markdoc. Cela activera l’analyse HTML dans les balises Markdoc.

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc({ allowHTML: true })],
});

Par défaut, tout contenu indenté de quatre espaces est traité comme un bloc de code. Malheureusement, ce comportement rend difficile l’utilisation de niveaux d’indentation arbitraires pour améliorer la lisibilité des documents à la structure complexe.

Lors de l’utilisation de balises imbriquées dans Markdoc, il peut être utile d’indenter le contenu à l’intérieur des balises afin que le niveau de profondeur soit clair. Pour prendre en charge l’indentation arbitraire, nous devons désactiver les blocs de code basés sur l’indentation et modifier plusieurs autres règles d’analyse markdown-it qui prennent en compte les blocs de code basés sur l’indentation. Ces modifications peuvent être appliquées en activant l’option ignoreIndentation.

astro.config.mjs
import { defineConfig } from 'astro/config';
import markdoc from '@astrojs/markdoc';
export default defineConfig({
// ...
integrations: [markdoc({ ignoreIndentation: true })],
});
# Bienvenue à Markdoc avec des balises indentées 👋
# Note : Vous pouvez utiliser des espaces ou des tabulations pour l'indentation.
{% custom-tag %}
{% custom-tag %} ### Les balises peuvent être indentées pour une meilleure lisibilité
{% another-custom-tag %}
Il est plus facile à suivre lorsqu'il y a beaucoup d'imbrications.
{% /another-custom-tag %}
{% /custom-tag %}
{% /custom-tag %}

Plus d'intégrations

Framework d'interface utilisateur

Adaptateurs SSR

Autres intégrations