Auteur:
    Création:2025-02-07Dernière mise à jour:2026-09-21

    Markdown / Contenu Texte Riche

    Intlayer prend en charge le contenu texte riche défini à l'aide de la syntaxe Markdown. Cela vous permet de rédiger et de gérer facilement du contenu avec une mise en forme avancée, comme des blogs, des articles, et bien plus encore.

    Déclarer du Contenu Markdown

    Vous pouvez déclarer du contenu Markdown en utilisant la fonction md ou simplement comme une chaîne de caractères (si elle contient de la syntaxe Markdown).

    Depuis la version 8.10.0, vous pouvez déclarer du contenu Markdown directement dans des fichiers .content.md. Intlayer détectera et analysera automatiquement le contenu Markdown.

    markdown-file.en.content.md
    ---
    key: my-markdown-content
    description: Mon contenu
    locale: en
    ---
    
    # Mon contenu
    
    Voici un exemple de contenu markdown
    

    Le champ front-matter locale permet de définir la langue du contenu. Il est optionnel. S'il n'est pas fourni, Intlayer utilisera la langue par défaut, qui sert également de langue de secours si aucune traduction n'est disponible pour une langue spécifique.

    Exemple de structure de fichiers :

    text
    content
    ├── markdown-file.en.content.md
    ├── markdown-file.fr.content.md
    └── markdown-file.es.content.md
    

    Vous pouvez ajouter dans le front-matter n'importe quelle propriété définie dans la Définition du dictionnaire

    Utilisez la fonction md pour déclarer explicitement du contenu Markdown. Cela est utile si vous voulez vous assurer qu'une chaîne est traitée comme du Markdown même si elle ne contient pas de syntaxe évidente.

    markdownDictionary.content.ts
    import { md, type Dictionary } from "intlayer";
    
    const markdownDictionary = {
    key: "app",
    content: {
      myMarkdownContent: md("## Mon titre \n\nLorem Ipsum"),
    },
    } satisfies Dictionary;
    
    export default markdownDictionary;
    

    Importez des fichiers .md directement en utilisant la fonction file.

    markdownDictionary.content.ts
    import { md, file, t } from "intlayer";
    
    export default {
    key: "app",
    content: {
      content: t({
        en: md(file("./myMarkdown.en.md")),
        fr: md(file("./myMarkdown.fr.md")),
      }),
    },
    };
    

    Si la chaîne de caractères contient des indicateurs Markdown courants (comme des en-têtes, des listes, des liens, etc.), Intlayer la transformera automatiquement.

    markdownDictionary.content.ts
    export default {
    key: "app",
    contentAutoTransformation: true, // Activer la détection automatique du Markdown - Peut être défini globalement dans intlayer.config.ts
    content: {
      myMarkdownContent: "## Mon titre \n\nLorem Ipsum",
    },
    };
    

    Rendu Markdown

    Intlayer propose deux manières indépendantes de rendre du Markdown :

    1. Via useIntlayer — Intlayer transforme automatiquement le nœud md dans le format natif du framework (JSX, VNode, chaîne HTML).

      • Le frontmatter est analysé et exposé sous .metadata. Vous pouvez remplacer le rendu à deux niveaux — globalement avec MarkdownProvider (ou l'équivalent du framework) et localement par nœud avec .use(). Les deux peuvent être combinés ; .use() est prioritaire sur MarkdownProvider, qui est lui-même prioritaire sur le rendu par défaut.
    2. Utilitaires d'aide<MarkdownRenderer />, useMarkdownRenderer() et renderMarkdown() sont des outils indépendants qui n'acceptent que des chaînes Markdown brutes. Ils sont indépendants de useIntlayer et ne fonctionnent pas avec les nœuds décorés qu'il retourne.

    Le rendu Markdown prend en charge MDX — utilisez n'importe quel composant JSX/framework par son nom directement dans votre Markdown.

    1. Rendu Automatique (via useIntlayer)

    Les nœuds Markdown peuvent être rendus directement sous forme de JSX.

    App.tsx
    import { useIntlayer } from "react-intlayer";
    import { MarkdownProvider } from "react-intlayer/markdown";
    
    const AppContent = () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return <div>{myMarkdownContent}</div>;
    };
    
    const App = () => (
    <MarkdownProvider
      components={{
        h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
        MyButton: (props) => <button {...props} />, // Composant MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Si MarkdownProvider n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Les nœuds Markdown peuvent être rendus directement sous forme de JSX.

    App.tsx
    import { useIntlayer } from "next-intlayer";
    import { MarkdownProvider } from "next-intlayer/markdown";
    
    const AppContent = () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return <div>{myMarkdownContent}</div>;
    };
    
    const App = () => (
    <MarkdownProvider
      components={{
        h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
        MyButton: (props) => <button {...props} />, // Composant MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Si MarkdownProvider n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Dans Vue, le contenu Markdown peut être rendu en utilisant la balise component intégrée ou directement comme un nœud.

    App.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    const { myMarkdownContent } = useIntlayer("app");
    </script>
    
    <template>
    <component :is="myMarkdownContent" />
    </template>
    

    Configurez globalement via le plugin intlayerMarkdown (prend en charge les composants personnalisés MDX) :

    main.ts
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    
    app.use(intlayerMarkdown, {
    components: {
      h1: (props) => h('h1', { style: { color: 'green' } }, props.children),
      MyButton: (props) => h('button', props), // Composant MDX
    },
    });
    
    Si le plugin intlayerMarkdown n'est pas installé, Intlayer effectuera le rendu avec le compilateur par défaut.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    vue
    <component :is="myMarkdownContent.use({
    h1: (props) => h('h1', { style: { color: 'red' } }, props.children),
    })" />
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    vue
    {{ myMarkdownContent.value }}
    {{ String(myMarkdownContent) }}
    {{ myMarkdownContent.toString() }}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    vue
    <component :is="myMarkdownContent.metadata" />
    <component :is="myMarkdownContent.metadata.title" />
    

    Svelte rend le Markdown sous forme de chaîne HTML par défaut. Utilisez {@html} pour le rendre.

    App.svelte
    <script lang="ts">
    import { useIntlayer } from "svelte-intlayer";
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    
    const content = useIntlayer("app");
    </script>
    
    <MarkdownProvider components={{ h1: MyHeading }}>
    {@html $content.myMarkdownContent}
    </MarkdownProvider>
    
    Si MarkdownProvider n'est pas présent, Intlayer rendra le markdown avec le compilateur par défaut.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    svelte
    {@html $content.myMarkdownContent.use({ ... })}
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    svelte
    {$content.myMarkdownContent.value}
    {String($content.myMarkdownContent)}
    {$content.myMarkdownContent.toString()}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    svelte
    {$content.myMarkdownContent.metadata}
    {$content.myMarkdownContent.metadata.title}
    

    Preact prend en charge les nœuds Markdown directement en JSX.

    App.tsx
    import { useIntlayer } from "preact-intlayer";
    import { MarkdownProvider } from "preact-intlayer/markdown";
    
    const AppContent = () => {
    const { myMarkdownContent } = useIntlayer("app");
    return <div>{myMarkdownContent}</div>;
    };
    
    const App = () => (
    <MarkdownProvider
      components={{
        h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
        MyButton: (props) => <button {...props} />, // Composant MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Si MarkdownProvider n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    tsx
    {myMarkdownContent.use({
    h1: ({ children }) => <h1 style={{ color: "red" }}>{children}</h1>,
    })}
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Solid prend en charge les nœuds Markdown directement en JSX.

    App.tsx
    import { useIntlayer } from "solid-intlayer";
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    const AppContent = () => {
    const { myMarkdownContent } = useIntlayer("app");
    return <div>{myMarkdownContent}</div>;
    };
    
    const App = () => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 style={{ color: "red" }}>{props.children}</h1>,
        MyButton: (props) => <button {...props} />, // Composant MDX
      }}
    >
      <AppContent />
    </MarkdownProvider>
    );
    
    Si MarkdownProvider n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    tsx
    {myMarkdownContent.use({
    h1: (props) => <h1 style={{ color: "red" }}>{props.children}</h1>,
    })}
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    tsx
    {myMarkdownContent.value}
    {String(myMarkdownContent)}
    {myMarkdownContent.toString()}
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    tsx
    {myMarkdownContent.metadata}
    {myMarkdownContent.metadata.title}
    

    Angular utilise la directive [innerHTML] pour afficher le contenu Markdown.

    app.component.ts
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
    selector: "app-root",
    template: `<div [innerHTML]="content().myMarkdownContent"></div>`,
    })
    export class AppComponent {
    content = useIntlayer("app");
    }
    
    Si le fournisseur IntlayerMarkdown n'est pas configuré, Intlayer effectuera le rendu avec le compilateur par défaut.

    Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode .use() :

    typescript
    content().myMarkdownContent.use({
    h1: { class: "text-3xl font-bold" },
    })
    

    Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :

    typescript
    content().myMarkdownContent.value
    String(content().myMarkdownContent)
    content().myMarkdownContent.toString()
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    typescript
    content().myMarkdownContent.metadata
    content().myMarkdownContent.metadata.title
    

    Dans Remix 3, les nœuds Markdown sont rendus sur le serveur en une chaîne HTML. Injectez-la avec la prop innerHTML de Remix JSX, ou avec html.raw dans une vue html-template.

    src/views/home.tsx
    import { useIntlayer } from "remix-intlayer";
    
    export const HomePage = () => () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return <div innerHTML={myMarkdownContent.value} />;
    };
    
    src/views/home.ts
    import { html } from "remix/html-template";
    import { useIntlayer } from "remix-intlayer";
    
    export const renderHomePage = () => {
    const { myMarkdownContent } = useIntlayer("app");
    
    return html.raw`<div>${myMarkdownContent.value}</div>`;
    };
    
    Remix échappe les valeurs interpolées par défaut. innerHTML et html.raw sont les deux mécanismes d'exclusion, ce dont une chaîne Markdown rendue a besoin.

    Vous pouvez également fournir des surcharges locales pour des balises spécifiques à l'aide de la méthode .use(). Les surcharges sont des fonctions renvoyant une chaîne HTML :

    tsx
    <div
    innerHTML={myMarkdownContent.use({
      h1: ({ children }) => `<h1 class="text-3xl font-bold">${children}</h1>`,
    })}
    />
    

    .value est la chaîne HTML rendue, tandis que String() / .toString() renvoient la source Markdown brute :

    tsx
    myMarkdownContent.value // "<h1>…</h1>"
    String(myMarkdownContent) // "# …"
    myMarkdownContent.toString() // "# …"
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    tsx
    myMarkdownContent.metadata
    myMarkdownContent.metadata.title
    

    Dans Astro, les nœuds Markdown sont rendus en une chaîne HTML. Injectez-la avec la directive set:html dans le template, ou avec innerHTML dans un <script> côté client.

    src/pages/index.astro
    ---
    import { useIntlayer } from "astro-intlayer";
    
    const { myMarkdownContent } = useIntlayer("app");
    ---
    
    <div set:html={myMarkdownContent.value} />
    
    src/components/Content.astro
    <div id="content"></div>
    
    <script>
    import { useIntlayer } from "astro-intlayer";
    
    const { myMarkdownContent } = useIntlayer("app");
    
    document.querySelector("#content")!.innerHTML = myMarkdownContent.value;
    </script>
    
    Astro échappe les {expressions} par défaut. set:html est le mécanisme d'exclusion, ce dont une chaîne Markdown rendue a besoin.

    Vous pouvez également fournir des surcharges locales pour des balises spécifiques à l'aide de la méthode .use(). Les surcharges sont des fonctions renvoyant une chaîne HTML :

    astro
    <div
    set:html={myMarkdownContent.use({
      h1: ({ children }) => `<h1 class="text-3xl font-bold">${children}</h1>`,
    })}
    />
    

    .value est la chaîne HTML rendue, tandis que String() / .toString() renvoient la source Markdown brute :

    astro
    myMarkdownContent.value // "<h1>…</h1>"
    String(myMarkdownContent) // "# …"
    myMarkdownContent.toString() // "# …"
    

    Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :

    astro
    myMarkdownContent.metadata
    myMarkdownContent.metadata.title
    

    2. Utilitaires d'aide (Chaînes Markdown Uniquement)

    Ces utilitaires rendent des chaînes Markdown brutes et sont indépendants de useIntlayer. Utilisez-les lorsque vous devez afficher du Markdown provenant de sources autres que vos dictionnaires.

    Composant <MarkdownRenderer />

    Rend une chaîne Markdown avec des options spécifiques.

    tsx
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Mon Titre"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Obtenez une fonction de rendu préconfigurée.

    tsx
    import { useMarkdownRenderer } from "react-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({
    forceBlock: true,
    components: { h1: (props) => <h1 {...props} className="custom" /> }
    });
    
    return renderMarkdown("# Mon Titre");
    

    Utilitaire renderMarkdown()

    Utilitaire autonome pour le rendu en dehors des composants.

    tsx
    import { renderMarkdown } from "react-intlayer/markdown";
    
    const jsx = renderMarkdown("# Mon Titre", { forceBlock: true });
    

    Composant <MarkdownRenderer />

    Rend une chaîne Markdown avec des options spécifiques.

    tsx
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true} tagfilter={true}>
    {"# Mon Titre"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    Obtenez une fonction de rendu préconfigurée.

    tsx
    import { useMarkdownRenderer } from "next-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({
    forceBlock: true,
    components: { h1: (props) => <h1 {...props} className="custom" /> }
    });
    
    return renderMarkdown("# Mon Titre");
    

    Utilitaire renderMarkdown()

    Utilitaire autonome pour le rendu en dehors des composants.

    tsx
    import { renderMarkdown } from "next-intlayer/markdown";
    
    const jsx = renderMarkdown("# Mon Titre", { forceBlock: true });
    

    Composant <MarkdownRenderer />

    vue
    <script setup>
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    </script>
    
    <template>
    <MarkdownRenderer :forceBlock="true" content="# Mon Titre" />
    </template>
    

    Composant <MarkdownRenderer />

    svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownRenderer forceBlock={true} value="# Mon Titre" />
    

    Hook useMarkdownRenderer()

    svelte
    <script lang="ts">
    import { useMarkdownRenderer } from "svelte-intlayer/markdown";
    const render = useMarkdownRenderer();
    </script>
    
    {@html render("# Mon Titre")}
    

    Utilitaire renderMarkdown()

    svelte
    <script lang="ts">
    import { renderMarkdown } from "svelte-intlayer/markdown";
    </script>
    
    {@html renderMarkdown("# Mon Titre")}
    

    Composant <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "preact-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Mon Titre"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "preact-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Mon Titre")}</div>;
    

    Utilitaire renderMarkdown()

    tsx
    import { renderMarkdown } from "preact-intlayer/markdown";
    
    return <div>{renderMarkdown("# Mon Titre")}</div>;
    

    Composant <MarkdownRenderer />

    tsx
    import { MarkdownRenderer } from "solid-intlayer/markdown";
    
    <MarkdownRenderer forceBlock={true}>
    {"# Mon Titre"}
    </MarkdownRenderer>
    

    Hook useMarkdownRenderer()

    tsx
    import { useMarkdownRenderer } from "solid-intlayer/markdown";
    
    const render = useMarkdownRenderer();
    
    return <div>{render("# Mon Titre")}</div>;
    

    Utilitaire renderMarkdown()

    tsx
    import { renderMarkdown } from "solid-intlayer/markdown";
    
    return <div>{renderMarkdown("# Mon Titre")}</div>;
    

    Service IntlayerMarkdownService

    Rend une chaîne Markdown en utilisant le service.

    typescript
    import { IntlayerMarkdownService } from "angular-intlayer/markdown";
    
    export class MyComponent {
    constructor(private markdownService: IntlayerMarkdownService) {}
    
    renderMarkdown(markdown: string) {
      return this.markdownService.renderMarkdown(markdown);
    }
    }
    

    Hook useMarkdownRenderer()

    Obtenez une fonction de rendu préconfigurée par installIntlayerMarkdown(). Elle renvoie une chaîne HTML.

    tsx
    import { useMarkdownRenderer } from "remix-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({ forceBlock: true });
    
    return <div innerHTML={renderMarkdown("# My Title")} />;
    

    Utilitaire renderMarkdown()

    Utilitaire autonome qui ignore la configuration globale.

    tsx
    import { renderMarkdown } from "remix-intlayer/markdown";
    
    const html = renderMarkdown("# My Title", { forceBlock: true });
    

    Hook useMarkdownRenderer()

    Obtenez une fonction de rendu préconfigurée par installIntlayerMarkdown(). Elle renvoie une chaîne HTML.

    astro
    ---
    import { useMarkdownRenderer } from "astro-intlayer/markdown";
    
    const renderMarkdown = useMarkdownRenderer({ forceBlock: true });
    ---
    
    <div set:html={renderMarkdown("# My Title")} />
    

    Utilitaire renderMarkdown()

    Utilitaire autonome qui ignore la configuration globale.

    astro
    ---
    import { renderMarkdown } from "astro-intlayer/markdown";
    
    const html = renderMarkdown("# My Title", { forceBlock: true });
    ---
    
    <div set:html={html} />
    

    Configuration Globale avec MarkdownProvider

    Le MarkdownProvider (ou son équivalent dans un framework) configure le pipeline de rendu Markdown pour toute votre application. Cela s'applique aussi bien au rendu automatique useIntlayer qu'aux utilitaires d'aide. Les options définies ici sont les options par défaut — .use() les remplace au niveau du nœud.

    AppProvider.tsx
    import { MarkdownProvider } from "react-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 style={{color: 'green'}} {...props} />,
        a: ({ href, ...props }) => <a style={{color: 'red'}} {...props} />,
        MyCustomJSXComponent: (props) => <span style={{color: 'red'}} {...props} />,
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    AppProvider.tsx
    import { MarkdownProvider } from "react-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        // Use dynamic import to reduce the bundle size of your application
        const { renderMarkdown } = await import('react-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    AppProvider.tsx
    import { MarkdownProvider } from "next-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 style={{color: 'green'}} {...props} />,
        a: ({ href, ...props }) => <a style={{color: 'red'}} {...props} />,
        MyCustomJSXComponent: (props) => <span style={{color: 'red'}} {...props} />,
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    AppProvider.tsx
    import { MarkdownProvider } from "next-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        // Use dynamic import to reduce the bundle size of your application
        const { renderMarkdown } = await import('next-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    main.ts
    import { createApp } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerMarkdown, {
    components: {
      h1: (props) =>
      h('h1', { style: { color: 'orange' }, ...props }, props.children),
      ComponentDemo: () => h('div', { style: { background: 'grey' } }, 'DEMO'),
      bold: (props) => h('strong', props),
      code: (props) => h('code', props),
    },
    });
    
    app.mount("#app");
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    main.ts
    import { createApp } from "vue";
    import { intlayer } from "vue-intlayer";
    import { intlayerMarkdown } from "vue-intlayer/markdown";
    import App from "./App.vue";
    
    const app = createApp(App);
    
    app.use(intlayer);
    app.use(intlayerMarkdown, {
    renderMarkdown: async (md) => {
      const { renderMarkdown } = await import('vue-intlayer/markdown');
      return renderMarkdown(md);
    },
    });
    
    app.mount("#app");
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    import MyHeading from "./MyHeading.svelte";
    </script>
    
    <MarkdownProvider
    components={{
      h1: MyHeading,
    }}
    >
    <slot />
    </MarkdownProvider>
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    App.svelte
    <script lang="ts">
    import { MarkdownProvider } from "svelte-intlayer/markdown";
    </script>
    
    <MarkdownProvider
    renderMarkdown={async (md) => {
      const { renderMarkdown } = await import('svelte-intlayer/markdown');
      return renderMarkdown(md);
    }}
    >
    <slot />
    </MarkdownProvider>
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    AppProvider.tsx
    import { MarkdownProvider } from "preact-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      components={{
        h1: ({ children }) => <h1 className="text-2xl font-bold">{children}</h1>,
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    AppProvider.tsx
    import { MarkdownProvider } from "preact-intlayer/markdown";
    
    export const AppProvider = ({ children }) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        const { renderMarkdown } = await import('preact-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {children}
    </MarkdownProvider>
    );
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    AppProvider.tsx
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    export const AppProvider = (props) => (
    <MarkdownProvider
      components={{
        h1: (props) => <h1 className="text-2xl font-bold">{props.children}</h1>,
      }}
    >
      {props.children}
    </MarkdownProvider>
    );
    
    MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. <MyCustomJSXComponent />) est résolu par rapport à la correspondance dans components.

    Vous pouvez également utiliser votre propre rendu de markdown :

    AppProvider.tsx
    import { MarkdownProvider } from "solid-intlayer/markdown";
    
    export const AppProvider = (props) => (
    <MarkdownProvider
      renderMarkdown={async (md) => {
        const { renderMarkdown } = await import('solid-intlayer/markdown');
        return renderMarkdown(md);
      }}
    >
      {props.children}
    </MarkdownProvider>
    );
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
    app.config.ts
    import { createIntlayerMarkdownProvider } from "angular-intlayer/markdown";
    
    export const appConfig: ApplicationConfig = {
    providers: [
      createIntlayerMarkdownProvider({
        components: {
          h1: { class: "text-2xl font-bold" },
        },
      }),
    ],
    };
    
    MDX est supporté — tout nom de composant utilisé dans votre Markdown (par exemple <MyCustomJSXComponent />) est résolu par rapport au mapping components.

    Vous pouvez également utiliser votre propre moteur de rendu Markdown :

    app.module.ts
    import { NgModule } from '@angular/core';
    import { IntlayerMarkdownModule } from 'angular-intlayer/markdown';
    
    @NgModule({
    imports: [
      IntlayerMarkdownModule.forRoot({
        renderMarkdown: async (md) => {
          const { renderMarkdown } = await import('angular-intlayer/markdown');
          return renderMarkdown(md);
        }
      })
    ]
    })
    export class AppModule {}
    
    L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.

    Remix n'a pas d'arbre de composants pour contenir un provider, la configuration est donc installée une seule fois, en tant que singleton, au démarrage du serveur. Elle configure le renderer renvoyé par useMarkdownRenderer(). Les nœuds md renvoyés par useIntlayer sont rendus avec le compilateur par défaut ; surchargez leurs balises par nœud avec .use().

    src/router.ts
    import { installIntlayerMarkdown } from "remix-intlayer/markdown";
    
    installIntlayerMarkdown({
    forceBlock: true,
    components: {
      h1: ({ children }) => `<h1 class="text-2xl font-bold">${children}</h1>`,
    },
    });
    

    Vous pouvez également utiliser votre propre rendu de markdown :

    src/router.ts
    import { installIntlayerMarkdown } from "remix-intlayer/markdown";
    
    installIntlayerMarkdown({
    renderMarkdown: async (md) => {
      const { marked } = await import("marked");
      return marked(md) as string;
    },
    });
    
    Utilisez installIntlayerMarkdownDynamic(async () => …) pour charger le renderer lui-même de manière paresseuse ; le chargeur ne s'exécute qu'au premier appel.

    Astro n'a pas d'arbre de composants pour contenir un provider, la configuration est donc installée une seule fois, en tant que singleton, dans le middleware (serveur) et dans un <script> côté client (navigateur). Elle configure le renderer renvoyé par useMarkdownRenderer(). Les nœuds md renvoyés par useIntlayer sont rendus avec le compilateur par défaut ; surchargez leurs balises par nœud avec .use().

    src/middleware.ts
    import { installIntlayerMarkdown } from "astro-intlayer/markdown";
    import { defineMiddleware } from "astro:middleware";
    
    // S'exécute une fois au démarrage du serveur ; le middleware Intlayer lui-même est
    // enregistré par l'intégration, en amont de ce fichier.
    installIntlayerMarkdown({
    forceBlock: true,
    components: {
      h1: ({ children }) => `<h1 class="text-2xl font-bold">${children}</h1>`,
    },
    });
    
    export const onRequest = defineMiddleware((_context, next) => next());
    

    Vous pouvez également utiliser votre propre rendu de markdown :

    src/middleware.ts
    import { installIntlayerMarkdown } from "astro-intlayer/markdown";
    
    installIntlayerMarkdown({
    renderMarkdown: async (md) => {
      const { marked } = await import("marked");
      return marked(md) as string;
    },
    });
    
    Utilisez installIntlayerMarkdownDynamic(async () => …) pour charger le renderer lui-même de manière paresseuse ; le chargeur ne s'exécute qu'au premier appel.

    Suspense

    Le moteur de rendu Markdown d'Intlayer est chargé dynamiquement. Bien qu'optimisé, le chunk de l'analyseur sous-jacent fait environ 55 ko. Son chargement synchrone retarde le rendu initial de la page et dégrade le First Contentful Paint (FCP).

    Pour éviter de bloquer l'interface utilisateur, Intlayer s'intègre à l'API Suspense de React. Il récupère l'analyseur en arrière-plan et lève une Promise pendant le téléchargement.

    Enveloppez tout composant rendant le Markdown d'Intlayer dans une limite <Suspense>. Cela affiche un état de repli localisé pendant le téléchargement du chunk, permettant au reste de votre DOM de se rendre immédiatement.

    Avertissement : Si vous ne fournissez pas de limite <Suspense>, React suspendra au niveau racine ou bloquera le rendu de tout l'arbre des composants jusqu'à ce que le chunk de 55 ko soit complètement chargé.

    Dans Next.js App Router, vous pouvez utiliser soit React Suspense pour les composants clients, soit un fichier loading.tsx pour les composants serveurs.

    Composant Client :

    components/MyComponent.tsx
    "use client";
    import { useIntlayer } from "next-intlayer";
    import { Suspense } from "react";
    
    const MyComponent = () => {
      const markdownContent = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Composant Serveur avec loading.tsx :

    app/loading.tsx
    export default function Loading() {
      return <div>Loading...</div>;
    }
    
    app/page.tsx
    import { useIntlayer } from "next-intlayer/server";
    
    const MyPage = () => {
      const markdownContent = useIntlayer("my-markdown");
      return <div>{markdownContent}</div>;
    };
    
    export default MyPage;
    
    tsx
    import { useIntlayer } from "react-intlayer";
    import { Suspense } from "react";
    
    const MyComponent = () => {
      const markdownContent = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Vue possède un composant <Suspense> intégré. Enveloppez le composant rendant le contenu Markdown dans une limite <Suspense>.

    MyComponent.vue
    <script setup>
    import { useIntlayer } from "vue-intlayer";
    
    const { markdownContent } = useIntlayer("my-markdown");
    </script>
    
    <template>
      <Suspense>
        <component :is="markdownContent" />
        <template #fallback>
          <div>Loading...</div>
        </template>
      </Suspense>
    </template>
    

    Svelte n'a pas d'équivalent à l'API Suspense. Utilisez un bloc {#await} pour gérer le rendu asynchrone du contenu Markdown.

    MyComponent.svelte
    <script lang="ts">
    import { useIntlayer } from "svelte-intlayer";
    
    const content = useIntlayer("my-markdown");
    </script>
    
    {#await $content.markdownContent}
      <div>Loading...</div>
    {:then rendered}
      {@html rendered}
    {/await}
    

    Preact prend en charge l'API Suspense de React via preact/compat.

    MyComponent.tsx
    import { useIntlayer } from "preact-intlayer";
    import { Suspense } from "preact/compat";
    
    const MyComponent = () => {
      const markdownContent = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Solid possède son propre composant <Suspense> provenant de solid-js.

    MyComponent.tsx
    import { useIntlayer } from "solid-intlayer";
    import { Suspense } from "solid-js";
    
    const MyComponent = () => {
      const { markdownContent } = useIntlayer("my-markdown");
    
      return (
        <Suspense fallback={<div>Loading...</div>}>{markdownContent}</Suspense>
      );
    };
    

    Angular n'a pas d'API Suspense. Utilisez les vues différées (@defer) d'Angular pour gérer le contenu Markdown chargé paresseusement (nécessite Angular 17+).

    my.component.ts
    import { Component } from "@angular/core";
    import { useIntlayer } from "angular-intlayer";
    
    @Component({
      selector: "app-my",
      template: `
        @defer {
          <div [innerHTML]="content().markdownContent"></div>
        } @loading {
          <div>Loading...</div>
        }
      `,
    })
    export class MyComponent {
      content = useIntlayer("my-markdown");
    }
    

    Rendu Côté Serveur (SSR) et Hydratation

    En comparaison avec d'autres parseurs Markdown tels que remark / rehype, Intlayer Markdown est sans dépendance et s'exécute aussi bien côté client que côté serveur.

    Cependant, Intlayer optimise l'analyse pour les frameworks de rendu côté serveur (SSR) (tels que Next.js App Router, React Router, Nuxt, SvelteKit, etc.).

    Au lieu d'envoyer des chaînes Markdown brutes au client et de les analyser dans le navigateur (ce qui entraîne une pénalité de performance), Intlayer vous permet de pré-analyser le Markdown en un arbre de syntaxe abstraite (AST) sur le serveur.

    Vous pouvez utiliser la fonction parseMarkdown du package Intlayer de votre framework côté serveur pour générer un AST sérialisable (objet ParsedMarkdown), et le transmettre directement au frontend. Tous les utilitaires de rendu Intlayer (comme <MarkdownRenderer>, useMarkdownRenderer, etc.) acceptent automatiquement cet objet AST et le rendent de manière transparente.

    Exemple dans une architecture Serveur/Client

    server.ts
    import { parseMarkdown } from "react-intlayer/markdown";
    
    // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
    export const loader = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Renvoyer l'AST au client sous forme de JSON
    return Response.json({ content: ast });
    };
    
    client.tsx
    import { useLoaderData } from "react-router";
    import { MarkdownRenderer } from "react-intlayer/markdown";
    
    // 2. Sur le client : Rendre l'AST directement sans ré-analyse
    export default function Page() {
    const { content } = useLoaderData();
    
    // Le renderer accepte soit une chaîne brute, soit l'AST analysé
    return <MarkdownRenderer content={content} />;
    }
    
    app/page.tsx
    import { parseMarkdown } from "next-intlayer/markdown";
    import { MarkdownRenderer } from "next-intlayer/markdown";
    
    export default async function Page() {
    // 1. Analyser le markdown en un AST sérialisable sur le serveur
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // 2. Rendre l'AST directement
    // Dans un composant serveur, cela fonctionne de manière transparente et transmet l'AST
    // directement aux composants clients sous-jacents si nécessaire.
    return <MarkdownRenderer content={ast} />;
    }
    
    pages/index.vue
    <script setup lang="ts">
    import { parseMarkdown } from "vue-intlayer/markdown";
    import { MarkdownRenderer } from "vue-intlayer/markdown";
    
    // 1. Récupérer et analyser le markdown en un AST sur le serveur
    const { data: ast } = await useAsyncData('markdown', () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    return parseMarkdown(markdownString);
    });
    </script>
    
    <template>
    <!-- 2. Sur le client : Rendre l'AST directement sans ré-analyse -->
    <MarkdownRenderer :content="ast" />
    </template>
    
    +page.server.ts
    import { parseMarkdown } from "svelte-intlayer/markdown";
    
    // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
    export const load = async () => {
    const markdownString = "## My title \n\nLorem Ipsum";
    const ast = parseMarkdown(markdownString);
    
    // Renvoyer l'AST au client
    return { content: ast };
    };
    
    +page.svelte
    <script lang="ts">
    import { MarkdownRenderer } from "svelte-intlayer/markdown";
    export let data;
    </script>
    
    <!-- 2. Sur le client : Rendre l'AST directement sans ré-analyse -->
    <MarkdownRenderer value={data.content} />
    

    L'SSR d'Angular résout généralement les données sur le serveur lors du chargement initial et s'hydrate sur le client. Vous pouvez utiliser des résolveurs pour transmettre l'AST.

    app.resolver.ts
    import { Injectable } from "@angular/core";
    import { Resolve } from "@angular/router";
    import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";
    
    @Injectable({ providedIn: "root" })
    export class MarkdownResolver implements Resolve<ParsedMarkdown> {
    resolve(): ParsedMarkdown {
      const markdownString = "## My title \n\nLorem Ipsum";
      // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
      return parseMarkdown(markdownString);
    }
    }
    
    app.component.ts
    import { Component } from "@angular/core";
    import { ActivatedRoute } from "@angular/router";
    import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";
    
    @Component({
    selector: "app-root",
    template: `<div [innerHTML]="renderedMarkdown"></div>`,
    })
    export class AppComponent {
    renderedMarkdown: string = "";
    
    constructor(
      private route: ActivatedRoute,
      private markdownService: IntlayerMarkdownService
    ) {
      // 2. Sur le client : Rendre l'AST directement sans ré-analyse
      this.route.data.subscribe((data) => {
        this.renderedMarkdown = this.markdownService.renderMarkdown(
          data.markdownAst
        ) as string;
      });
    }
    }
    

    Remix 3 effectue le rendu sur le serveur et diffuse le HTML, aucun AST n'a donc besoin d'être transmis au client. Analysez-le une seule fois et rendez l'AST là où la page est construite :

    src/views/article.tsx
    import { parseMarkdown, renderMarkdown } from "remix-intlayer/markdown";
    
    // 1. Analyser le markdown en un AST sérialisable (ex. une fois, au chargement du module)
    const ast = parseMarkdown("## My title \n\nLorem Ipsum");
    
    export const ArticlePage = () => () => (
    // 2. Rendre l'AST : le renderer accepte une chaîne brute ou l'AST analysé
    <article innerHTML={renderMarkdown(ast)} />
    );
    

    Les pages Astro sont rendues sur le serveur, aucun AST n'a donc besoin d'être transmis au client. Analysez le Markdown dans le frontmatter et rendez-le avec set:html :

    src/pages/article.astro
    ---
    import { parseMarkdown, renderMarkdown } from "astro-intlayer/markdown";
    
    // 1. Analyser le markdown en un AST sérialisable
    const ast = parseMarkdown("## My title \n\nLorem Ipsum");
    ---
    
    <!-- 2. Rendre l'AST : le renderer accepte une chaîne brute ou l'AST analysé -->
    <article set:html={renderMarkdown(ast)} />
    

    Ce modèle garantit que la logique d'analyse Markdown est entièrement exécutée sur le serveur, ce qui réduit considérablement le temps d'exécution côté client et améliore la vitesse d'hydratation initiale.

    Référence des options

    Ces options peuvent être passées à MarkdownProvider, MarkdownRenderer, useMarkdownRenderer et renderMarkdown.

    OptionTypeDefaultDescription
    forceBlockbooleanfalseForce la sortie à être enveloppée dans un élément de niveau bloc (ex: <div>).
    forceInlinebooleanfalseForce la sortie à être enveloppée dans un élément en ligne (ex: <span>).
    tagfilterbooleantrueActive le GitHub Tag Filter pour une meilleure sécurité en supprimant les balises HTML dangereuses.
    preserveFrontmatterbooleanfalseSi true, le frontmatter au début de la chaîne Markdown ne sera pas supprimé.
    componentsOverrides{}Une carte des balises HTML vers des composants personnalisés (ex: { h1: MyHeading }).
    wrapperComponentnullUn composant personnalisé pour envelopper le Markdown rendu.
    renderMarkdownFunctionnullUne fonction de rendu personnalisée pour remplacer complètement le compilateur Markdown par défaut.