\n\n \n \n \n ```\n\n Configurez globalement via le plugin `intlayerMarkdown` (prend en charge les composants personnalisés MDX) :\n\n ```ts fileName=\"main.ts\"\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n\n app.use(intlayerMarkdown, {\n components: {\n h1: (props) => h('h1', { style: { color: 'green' } }, props.children),\n MyButton: (props) => h('button', props), // Composant MDX\n },\n });\n ```\n\n > Si le plugin `intlayerMarkdown` n'est pas installé, Intlayer effectuera le rendu avec le compilateur par défaut.\n\n Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode `.use()` :\n\n ```vue\n h('h1', { style: { color: 'red' } }, props.children),\n })\" />\n ```\n\n Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :\n\n ```vue\n {{ myMarkdownContent.value }}\n {{ String(myMarkdownContent) }}\n {{ myMarkdownContent.toString() }}\n ```\n\n Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :\n\n ```vue\n \n \n ```\n\n \n \n Svelte rend le Markdown sous forme de chaîne HTML par défaut. Utilisez `{@html}` pour le rendre.\n\n ```svelte fileName=\"App.svelte\"\n \n\n \n {@html $content.myMarkdownContent}\n \n ```\n\n > Si `MarkdownProvider` n'est pas présent, Intlayer rendra le markdown avec le compilateur par défaut.\n\n Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode `.use()` :\n\n ```svelte\n {@html $content.myMarkdownContent.use({ ... })}\n ```\n\n Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :\n\n ```svelte\n {$content.myMarkdownContent.value}\n {String($content.myMarkdownContent)}\n {$content.myMarkdownContent.toString()}\n ```\n\n Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :\n\n ```svelte\n {$content.myMarkdownContent.metadata}\n {$content.myMarkdownContent.metadata.title}\n ```\n\n \n \n Preact prend en charge les nœuds Markdown directement en JSX.\n\n ```tsx fileName=\"App.tsx\"\n import { useIntlayer } from \"preact-intlayer\";\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n const AppContent = () => {\n const { myMarkdownContent } = useIntlayer(\"app\");\n return
{myMarkdownContent}
;\n };\n\n const App = () => (\n
{children}
,\n MyButton: (props) => , // Composant MDX\n }}\n >\n \n \n );\n ```\n\n > Si `MarkdownProvider` n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.\n\n Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode `.use()` :\n\n ```tsx\n {myMarkdownContent.use({\n h1: ({ children }) =>
{children}
,\n })}\n ```\n\n Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Solid prend en charge les nœuds Markdown directement en JSX.\n\n ```tsx fileName=\"App.tsx\"\n import { useIntlayer } from \"solid-intlayer\";\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n const AppContent = () => {\n const { myMarkdownContent } = useIntlayer(\"app\");\n return
{myMarkdownContent}
;\n };\n\n const App = () => (\n
{props.children}
,\n MyButton: (props) => , // Composant MDX\n }}\n >\n \n \n );\n ```\n\n > Si `MarkdownProvider` n'est pas présent, Intlayer rendra le markdown en utilisant le parser par défaut de Markdown vers JSX.\n\n Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode `.use()` :\n\n ```tsx\n {myMarkdownContent.use({\n h1: (props) =>
{props.children}
,\n })}\n ```\n\n Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Angular utilise la directive `[innerHTML]` pour afficher le contenu Markdown.\n\n ```typescript fileName=\"app.component.ts\"\n import { Component } from \"@angular/core\";\n import { useIntlayer } from \"angular-intlayer\";\n\n @Component({\n selector: \"app-root\",\n template: ``,\n })\n export class AppComponent {\n content = useIntlayer(\"app\");\n }\n ```\n\n > Si le fournisseur IntlayerMarkdown n'est pas configuré, Intlayer effectuera le rendu avec le compilateur par défaut.\n\n Vous pouvez également fournir des remplacements locaux pour des nœuds spécifiques en utilisant la méthode `.use()` :\n\n ```typescript\n content().myMarkdownContent.use({\n h1: { class: \"text-3xl font-bold\" },\n })\n ```\n\n Vous pouvez récupérer le Markdown sous forme de chaîne de caractères :\n\n ```typescript\n content().myMarkdownContent.value\n String(content().myMarkdownContent)\n content().myMarkdownContent.toString()\n ```\n\n Et vous pouvez accéder aux métadonnées de votre markdown comme ceci :\n\n ```typescript\n content().myMarkdownContent.metadata\n content().myMarkdownContent.metadata.title\n ```\n\n \n\n\n### 2. Utilitaires d'aide (Chaînes Markdown Uniquement)\n\nCes 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.\n\n\n \n \n #### Composant ``\n\n Rend une chaîne Markdown avec des options spécifiques.\n\n ```tsx\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n \n {\"# Mon Titre\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Obtenez une fonction de rendu préconfigurée.\n\n ```tsx\n import { useMarkdownRenderer } from \"react-intlayer/markdown\";\n\n const renderMarkdown = useMarkdownRenderer({\n forceBlock: true,\n components: { h1: (props) => }\n });\n\n return renderMarkdown(\"# Mon Titre\");\n ```\n\n #### Utilitaire `renderMarkdown()`\n Utilitaire autonome pour le rendu en dehors des composants.\n\n ```tsx\n import { renderMarkdown } from \"react-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Mon Titre\", { forceBlock: true });\n ```\n\n \n \n \n #### Composant ``\n\n Rend une chaîne Markdown avec des options spécifiques.\n\n ```tsx\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n \n {\"# Mon Titre\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Obtenez une fonction de rendu préconfigurée.\n\n ```tsx\n import { useMarkdownRenderer } from \"next-intlayer/markdown\";\n\n const renderMarkdown = useMarkdownRenderer({\n forceBlock: true,\n components: { h1: (props) => }\n });\n\n return renderMarkdown(\"# Mon Titre\");\n ```\n\n #### Utilitaire `renderMarkdown()`\n Utilitaire autonome pour le rendu en dehors des composants.\n\n ```tsx\n import { renderMarkdown } from \"next-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Mon Titre\", { forceBlock: true });\n ```\n\n \n \n\n #### Composant ``\n\n ```vue\n \n\n \n \n \n ```\n\n \n \n\n #### Composant ``\n\n ```svelte\n \n\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n ```svelte\n \n\n {@html render(\"# Mon Titre\")}\n ```\n\n #### Utilitaire `renderMarkdown()`\n\n ```svelte\n \n\n {@html renderMarkdown(\"# Mon Titre\")}\n ```\n\n \n \n #### Composant ``\n\n ```tsx\n import { MarkdownRenderer } from \"preact-intlayer/markdown\";\n\n \n {\"# Mon Titre\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n ```tsx\n import { useMarkdownRenderer } from \"preact-intlayer/markdown\";\n\n const render = useMarkdownRenderer();\n\n return
;\n ```\n\n \n \n #### Service `IntlayerMarkdownService`\n Rend une chaîne Markdown en utilisant le service.\n\n ```typescript\n import { IntlayerMarkdownService } from \"angular-intlayer/markdown\";\n\n export class MyComponent {\n constructor(private markdownService: IntlayerMarkdownService) {}\n\n renderMarkdown(markdown: string) {\n return this.markdownService.renderMarkdown(markdown);\n }\n }\n ```\n\n \n\n\n## Configuration Globale avec `MarkdownProvider`\n\nLe `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.\n\n\n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"react-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n ,\n a: ({ href, ...props }) => ,\n MyCustomJSXComponent: (props) => ,\n }}\n >\n {children}\n \n );\n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"react-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n // Use dynamic import to reduce the bundle size of your application\n const { renderMarkdown } = await import('react-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"next-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n ,\n a: ({ href, ...props }) => ,\n MyCustomJSXComponent: (props) => ,\n }}\n >\n {children}\n \n );\n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"next-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n // Use dynamic import to reduce the bundle size of your application\n const { renderMarkdown } = await import('next-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```typescript fileName=\"main.ts\"\n import { createApp } from \"vue\";\n import { intlayer } from \"vue-intlayer\";\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n import App from \"./App.vue\";\n\n const app = createApp(App);\n\n app.use(intlayer);\n app.use(intlayerMarkdown, {\n components: {\n h1: (props) =>\n h('h1', { style: { color: 'orange' }, ...props }, props.children),\n ComponentDemo: () => h('div', { style: { background: 'grey' } }, 'DEMO'),\n bold: (props) => h('strong', props),\n code: (props) => h('code', props),\n },\n });\n\n app.mount(\"#app\");\n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```typescript fileName=\"main.ts\"\n import { createApp } from \"vue\";\n import { intlayer } from \"vue-intlayer\";\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n import App from \"./App.vue\";\n\n const app = createApp(App);\n\n app.use(intlayer);\n app.use(intlayerMarkdown, {\n renderMarkdown: async (md) => {\n const { renderMarkdown } = await import('vue-intlayer/markdown');\n return renderMarkdown(md);\n },\n });\n\n app.mount(\"#app\");\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```svelte fileName=\"App.svelte\"\n \n\n \n \n \n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```svelte fileName=\"App.svelte\"\n \n\n {\n const { renderMarkdown } = await import('svelte-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n \n \n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n
{children}
,\n }}\n >\n {children}\n \n );\n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n const { renderMarkdown } = await import('preact-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n export const AppProvider = (props) => (\n
{props.children}
,\n }}\n >\n {props.children}\n \n );\n ```\n\n\n > MDX est pris en charge — tout nom de composant utilisé dans votre Markdown (ex. ``) est résolu par rapport à la correspondance dans `components`.\n\n Vous pouvez également utiliser votre propre rendu de markdown :\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n export const AppProvider = (props) => (\n {\n const { renderMarkdown } = await import('solid-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {props.children}\n \n );\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n \n\n ```typescript fileName=\"app.module.ts\"\n import { NgModule } from '@angular/core';\n import { IntlayerMarkdownModule } from 'angular-intlayer/markdown';\n\n @NgModule({\n imports: [\n IntlayerMarkdownModule.forRoot({\n renderMarkdown: async (md) => {\n const { renderMarkdown } = await import('angular-intlayer/markdown');\n return renderMarkdown(md);\n }\n })\n ]\n })\n export class AppModule {}\n ```\n\n > L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.\n\n \n\n\n## Suspense\n\nLe 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).\n\nPour é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.\n\nEnveloppez tout composant rendant le Markdown d'Intlayer dans une limite ``. 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.\n\nAvertissement : Si vous ne fournissez pas de limite ``, 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é.\n\n\n \n\nDans Next.js App Router, vous pouvez utiliser soit React `Suspense` pour les composants clients, soit un fichier `loading.tsx` pour les composants serveurs.\n\n**Composant Client :**\n\n```tsx fileName=\"components/MyComponent.tsx\"\n\"use client\";\nimport { useIntlayer } from \"next-intlayer\";\nimport { Suspense } from \"react\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n**Composant Serveur avec `loading.tsx` :**\n\n```tsx fileName=\"app/loading.tsx\"\nexport default function Loading() {\n return
;\n};\n\nexport default MyPage;\n```\n\n \n\n \n\n```tsx\nimport { useIntlayer } from \"react-intlayer\";\nimport { Suspense } from \"react\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n \n\nVue possède un composant `` intégré. Enveloppez le composant rendant le contenu Markdown dans une limite ``.\n\n```vue fileName=\"MyComponent.vue\"\n\n\n\n \n \n \n
Loading...
\n \n \n\n```\n\n \n \n\nSvelte n'a pas d'équivalent à l'API Suspense. Utilisez un bloc `{#await}` pour gérer le rendu asynchrone du contenu Markdown.\n\n```svelte fileName=\"MyComponent.svelte\"\n\n\n{#await $content.markdownContent}\n
Loading...
\n{:then rendered}\n {@html rendered}\n{/await}\n```\n\n \n \n\nPreact prend en charge l'API Suspense de React via `preact/compat`.\n\n```tsx fileName=\"MyComponent.tsx\"\nimport { useIntlayer } from \"preact-intlayer\";\nimport { Suspense } from \"preact/compat\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n\nSolid possède son propre composant `` provenant de `solid-js`.\n\n```tsx fileName=\"MyComponent.tsx\"\nimport { useIntlayer } from \"solid-intlayer\";\nimport { Suspense } from \"solid-js\";\n\nconst MyComponent = () => {\n const { markdownContent } = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n\nAngular 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+).\n\n```typescript fileName=\"my.component.ts\"\nimport { Component } from \"@angular/core\";\nimport { useIntlayer } from \"angular-intlayer\";\n\n@Component({\n selector: \"app-my\",\n template: `\n @defer {\n \n } @loading {\n
Loading...
\n }\n `,\n})\nexport class MyComponent {\n content = useIntlayer(\"my-markdown\");\n}\n```\n\n \n\n\n---\n\n## Rendu Côté Serveur (SSR) et Hydratation\n\nEn 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.\n\nCependant, Intlayer optimise l'analyse pour les frameworks de rendu côté serveur (SSR) (tels que Next.js App Router, React Router, Nuxt, SvelteKit, etc.).\n\nAu 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.\n\nVous 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 ``, `useMarkdownRenderer`, etc.) acceptent automatiquement cet objet AST et le rendent de manière transparente.\n\n### Exemple dans une architecture Serveur/Client\n\n\n \n\n ```tsx fileName=\"server.ts\"\n import { parseMarkdown } from \"react-intlayer/markdown\";\n\n // 1. Sur le serveur : Analyser le markdown en un AST sérialisable\n export const loader = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Renvoyer l'AST au client sous forme de JSON\n return Response.json({ content: ast });\n };\n ```\n\n ```tsx fileName=\"client.tsx\"\n import { useLoaderData } from \"react-router\";\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n // 2. Sur le client : Rendre l'AST directement sans ré-analyse\n export default function Page() {\n const { content } = useLoaderData();\n\n // Le renderer accepte soit une chaîne brute, soit l'AST analysé\n return ;\n }\n ```\n\n \n \n\n ```tsx fileName=\"app/page.tsx\"\n import { parseMarkdown } from \"next-intlayer/markdown\";\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n export default async function Page() {\n // 1. Analyser le markdown en un AST sérialisable sur le serveur\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // 2. Rendre l'AST directement\n // Dans un composant serveur, cela fonctionne de manière transparente et transmet l'AST\n // directement aux composants clients sous-jacents si nécessaire.\n return ;\n }\n ```\n\n \n \n\n ```vue fileName=\"pages/index.vue\"\n \n\n \n \n \n \n ```\n\n \n \n\n ```typescript fileName=\"+page.server.ts\"\n import { parseMarkdown } from \"svelte-intlayer/markdown\";\n\n // 1. Sur le serveur : Analyser le markdown en un AST sérialisable\n export const load = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Renvoyer l'AST au client\n return { content: ast };\n };\n ```\n\n ```svelte fileName=\"+page.svelte\"\n \n\n \n \n ```\n\n \n \n\n 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.\n\n ```typescript fileName=\"app.resolver.ts\"\n import { Injectable } from \"@angular/core\";\n import { Resolve } from \"@angular/router\";\n import { parseMarkdown, type ParsedMarkdown } from \"angular-intlayer/markdown\";\n\n @Injectable({ providedIn: \"root\" })\n export class MarkdownResolver implements Resolve {\n resolve(): ParsedMarkdown {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n // 1. Sur le serveur : Analyser le markdown en un AST sérialisable\n return parseMarkdown(markdownString);\n }\n }\n ```\n\n ```typescript fileName=\"app.component.ts\"\n import { Component } from \"@angular/core\";\n import { ActivatedRoute } from \"@angular/router\";\n import { IntlayerMarkdownService, type ParsedMarkdown } from \"angular-intlayer/markdown\";\n\n @Component({\n selector: \"app-root\",\n template: ``,\n })\n export class AppComponent {\n renderedMarkdown: string = \"\";\n\n constructor(\n private route: ActivatedRoute,\n private markdownService: IntlayerMarkdownService\n ) {\n // 2. Sur le client : Rendre l'AST directement sans ré-analyse\n this.route.data.subscribe((data) => {\n this.renderedMarkdown = this.markdownService.renderMarkdown(\n data.markdownAst\n ) as string;\n });\n }\n }\n ```\n\n \n\n\nCe 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.\n\n## Référence des options\n\nCes options peuvent être passées à `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` et `renderMarkdown`.\n\n| Option | Type | Default | Description |\n| :-------------------- | :---------- | :------ | :-------------------------------------------------------------------------------------------------- |\n| `forceBlock` | `boolean` | `false` | Force la sortie à être enveloppée dans un élément de niveau bloc (ex: `
`). |\n| `forceInline` | `boolean` | `false` | Force la sortie à être enveloppée dans un élément en ligne (ex: ``). |\n| `tagfilter` | `boolean` | `true` | Active le GitHub Tag Filter pour une meilleure sécurité en supprimant les balises HTML dangereuses. |\n| `preserveFrontmatter` | `boolean` | `false` | Si `true`, le frontmatter au début de la chaîne Markdown ne sera pas supprimé. |\n| `components` | `Overrides` | `{}` | Une carte des balises HTML vers des composants personnalisés (ex: `{ h1: MyHeading }`). |\n| `wrapper` | `Component` | `null` | Un composant personnalisé pour envelopper le Markdown rendu. |\n| `renderMarkdown` | `Function` | `null` | Une fonction de rendu personnalisée pour remplacer complètement le compilateur Markdown par défaut. |\n","description":"Découvrez comment déclarer et utiliser du contenu Markdown sur votre site multilingue avec Intlayer. Suivez les étapes de cette documentation en ligne pour intégrer facilement Markdown à votre projet.","url":"https://intlayer.org/fr/doc/concept/content/markdown","datePublished":"2025-02-07","dateModified":"2026-05-19","version":"8.11.0","keywords":"Markdown, Internationalisation, Documentation, Intlayer, Next.js, JavaScript, React","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Développeurs, Responsables de contenu"}}
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
Copier le code
Copier le code dans le presse-papiers
---key: my-markdown-contentdescription: Mon contenulocale: en---# Mon contenuVoici 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.
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
Copier le code
Copier le code dans le presse-papiers
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.
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
Copier le code
Copier le code dans le presse-papiers
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 :
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.
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.
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.
import { renderMarkdown } from "solid-intlayer/markdown";return <div>{renderMarkdown("# Mon Titre")}</div>;
Service IntlayerMarkdownService
Rend une chaîne Markdown en utilisant le service.
typescript
Copier le code
Copier le code dans le presse-papiers
import { IntlayerMarkdownService } from "angular-intlayer/markdown";export class MyComponent { constructor(private markdownService: IntlayerMarkdownService) {} renderMarkdown(markdown: string) { return this.markdownService.renderMarkdown(markdown); }}
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.
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
Copier le code
Copier le code dans le presse-papiers
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.
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
Copier le code
Copier le code dans le presse-papiers
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.
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
Copier le code
Copier le code dans le presse-papiers
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
Copier le code
Copier le code dans le presse-papiers
<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 :
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
Copier le code
Copier le code dans le presse-papiers
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 :
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 :
L'import dynamique de votre système de rendu Markdown est un bon moyen de réduire la taille du bundle de votre application.
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.
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
Copier le code
Copier le code dans le presse-papiers
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
Copier le code
Copier le code dans le presse-papiers
import { parseMarkdown } from "react-intlayer/markdown";// 1. Sur le serveur : Analyser le markdown en un AST sérialisableexport 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
Copier le code
Copier le code dans le presse-papiers
import { useLoaderData } from "react-router";import { MarkdownRenderer } from "react-intlayer/markdown";// 2. Sur le client : Rendre l'AST directement sans ré-analyseexport 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
Copier le code
Copier le code dans le presse-papiers
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
Copier le code
Copier le code dans le presse-papiers
<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 serveurconst { 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
Copier le code
Copier le code dans le presse-papiers
import { parseMarkdown } from "svelte-intlayer/markdown";// 1. Sur le serveur : Analyser le markdown en un AST sérialisableexport const load = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Renvoyer l'AST au client return { content: ast };};
+page.svelte
Copier le code
Copier le code dans le presse-papiers
<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
Copier le code
Copier le code dans le presse-papiers
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
Copier le code
Copier le code dans le presse-papiers
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; }); }}
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.
Afficher tout le contenu du tableau
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
Option
Type
Default
Description
forceBlock
boolean
false
Force la sortie à être enveloppée dans un élément de niveau bloc (ex: <div>).
forceInline
boolean
false
Force la sortie à être enveloppée dans un élément en ligne (ex: <span>).
tagfilter
boolean
true
Active le GitHub Tag Filter pour une meilleure sécurité en supprimant les balises HTML dangereuses.
preserveFrontmatter
boolean
false
Si true, le frontmatter au début de la chaîne Markdown ne sera pas supprimé.
components
Overrides
{}
Une carte des balises HTML vers des composants personnalisés (ex: { h1: MyHeading }).
wrapper
Component
null
Un composant personnalisé pour envelopper le Markdown rendu.
renderMarkdown
Function
null
Une fonction de rendu personnalisée pour remplacer complètement le compilateur Markdown par défaut.