@intlayer/docs 8.11.1 → 8.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/blog/en/i18n_using_next-i18next.md +3 -3
  2. package/blog/en/i18n_using_next-intl.md +3 -3
  3. package/blog/en/list_i18n_technologies/frameworks/angular.md +3 -3
  4. package/blog/en/list_i18n_technologies/frameworks/react-native.md +3 -3
  5. package/blog/en/list_i18n_technologies/frameworks/react.md +3 -3
  6. package/blog/en/list_i18n_technologies/frameworks/svelte.md +3 -3
  7. package/blog/en/list_i18n_technologies/frameworks/vue.md +3 -3
  8. package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +3 -3
  9. package/dist/cjs/generated/blog.entry.cjs +0 -1
  10. package/dist/cjs/generated/blog.entry.cjs.map +1 -1
  11. package/dist/cjs/generated/docs.entry.cjs +0 -1
  12. package/dist/cjs/generated/docs.entry.cjs.map +1 -1
  13. package/dist/cjs/generated/frequentQuestions.entry.cjs +0 -1
  14. package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
  15. package/dist/cjs/generated/legal.entry.cjs +0 -1
  16. package/dist/cjs/generated/legal.entry.cjs.map +1 -1
  17. package/docs/ar/dictionary/markdown.md +161 -0
  18. package/docs/de/dictionary/markdown.md +161 -0
  19. package/docs/en/dictionary/markdown.md +163 -0
  20. package/docs/en/intlayer_with_adonisjs.md +3 -3
  21. package/docs/en/intlayer_with_analog.md +3 -3
  22. package/docs/en/intlayer_with_angular_19.md +3 -3
  23. package/docs/en/intlayer_with_angular_21.md +3 -3
  24. package/docs/en/intlayer_with_astro.md +3 -3
  25. package/docs/en/intlayer_with_astro_lit.md +3 -3
  26. package/docs/en/intlayer_with_astro_preact.md +3 -3
  27. package/docs/en/intlayer_with_astro_react.md +3 -3
  28. package/docs/en/intlayer_with_astro_solid.md +3 -3
  29. package/docs/en/intlayer_with_astro_svelte.md +3 -3
  30. package/docs/en/intlayer_with_astro_vanilla.md +3 -3
  31. package/docs/en/intlayer_with_astro_vue.md +3 -3
  32. package/docs/en/intlayer_with_create_react_app.md +3 -3
  33. package/docs/en/intlayer_with_express.md +3 -3
  34. package/docs/en/intlayer_with_fastify.md +3 -3
  35. package/docs/en/intlayer_with_hono.md +3 -3
  36. package/docs/en/intlayer_with_lynx+react.md +3 -3
  37. package/docs/en/intlayer_with_nestjs.md +3 -3
  38. package/docs/en/intlayer_with_next-i18next.md +3 -3
  39. package/docs/en/intlayer_with_next-intl.md +3 -3
  40. package/docs/en/intlayer_with_nextjs_14.md +3 -3
  41. package/docs/en/intlayer_with_nextjs_15.md +3 -3
  42. package/docs/en/intlayer_with_nextjs_16.md +3 -3
  43. package/docs/en/intlayer_with_nextjs_compiler.md +3 -3
  44. package/docs/en/intlayer_with_nextjs_no_locale_path.md +3 -3
  45. package/docs/en/intlayer_with_nextjs_page_router.md +3 -3
  46. package/docs/en/intlayer_with_nuxt.md +3 -3
  47. package/docs/en/intlayer_with_react_native+expo.md +3 -3
  48. package/docs/en/intlayer_with_react_router_v7.md +3 -3
  49. package/docs/en/intlayer_with_react_router_v7_fs_routes.md +3 -3
  50. package/docs/en/intlayer_with_svelte_kit.md +3 -3
  51. package/docs/en/intlayer_with_tanstack+solid.md +3 -3
  52. package/docs/en/intlayer_with_tanstack.md +3 -3
  53. package/docs/en/intlayer_with_vanilla.md +3 -3
  54. package/docs/en/intlayer_with_vite+lit.md +3 -3
  55. package/docs/en/intlayer_with_vite+preact.md +3 -3
  56. package/docs/en/intlayer_with_vite+react.md +3 -3
  57. package/docs/en/intlayer_with_vite+react_compiler.md +3 -3
  58. package/docs/en/intlayer_with_vite+solid.md +3 -3
  59. package/docs/en/intlayer_with_vite+svelte.md +3 -3
  60. package/docs/en/intlayer_with_vite+vanilla.md +3 -3
  61. package/docs/en/intlayer_with_vite+vue.md +3 -3
  62. package/docs/en-GB/dictionary/markdown.md +161 -0
  63. package/docs/es/dictionary/markdown.md +161 -0
  64. package/docs/fr/dictionary/markdown.md +161 -0
  65. package/docs/hi/dictionary/markdown.md +161 -0
  66. package/docs/id/dictionary/markdown.md +161 -0
  67. package/docs/it/dictionary/markdown.md +161 -0
  68. package/docs/ko/dictionary/markdown.md +161 -0
  69. package/docs/pl/dictionary/markdown.md +161 -0
  70. package/docs/pt/dictionary/markdown.md +161 -0
  71. package/docs/ru/dictionary/markdown.md +161 -0
  72. package/docs/tr/dictionary/markdown.md +161 -0
  73. package/docs/uk/dictionary/markdown.md +161 -0
  74. package/docs/vi/dictionary/markdown.md +161 -0
  75. package/docs/zh/dictionary/markdown.md +161 -0
  76. package/package.json +7 -7
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2026-03-31
3
- updatedAt: 2026-05-06
4
- title: Vanilla JS i18n - How to translate a Vanilla JS app in 2026
5
- description: Discover how to make your Vanilla JS website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vanilla JS i18n - Complete guide to translate a Vanilla JS app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vanilla JS website multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2026-03-23
3
- updatedAt: 2026-05-06
4
- title: Vite + Lit i18n - How to translate a Lit app in 2026
5
- description: Discover how to make your Vite and Lit website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Lit i18n - Complete guide to translate a Lit app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Lit application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2025-04-18
3
- updatedAt: 2026-05-06
4
- title: Vite + Preact i18n - How to translate an Preact app in 2026
5
- description: Discover how to make your Vite and Preact website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Preact i18n - Complete guide to translate a Preact app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Preact application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2024-03-07
3
- updatedAt: 2026-05-06
4
- title: Vite + React i18n - How to translate an React app in 2026
5
- description: Learn how to add internationalization (i18n) to your Vite and React application using Intlayer. Follow this guide to make your app multilingual.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + React i18n - Complete guide to translate a React app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + React application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2024-03-07
3
- updatedAt: 2026-05-06
4
- title: Vite + React i18n - Transform an existing app into a multilingual app in 2026
5
- description: Discover how to make your existing Vite and React application multilingual using Intlayer Compiler. Follow the documentation to internationalize (i18n) and translate it with AI.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + React i18n - Complete guide to migrate an existing app with Intlayer
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your existing Vite + React application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2025-04-18
3
- updatedAt: 2026-05-06
4
- title: Vite + Solid i18n - How to translate an Solid app in 2026
5
- description: Discover how to make your Vite and Solid website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Solid i18n - Complete guide to translate a Solid app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Solid application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2025-04-18
3
- updatedAt: 2026-05-06
4
- title: Vite + Svelte i18n - How to translate an Svelte app in 2026
5
- description: Discover how to make your Vite and Svelte website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Svelte i18n - Complete guide to translate a Svelte app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Svelte application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2026-03-23
3
- updatedAt: 2026-05-06
4
- title: Vite + Vanilla JS i18n - How to translate a Vanilla JS app in 2026
5
- description: Discover how to make your Vite and Vanilla JS website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Vanilla JS i18n - Complete guide to translate a Vanilla JS app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Vanilla JS application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  createdAt: 2025-04-18
3
- updatedAt: 2026-05-06
4
- title: Vite + Vue i18n - How to translate an Vue app in 2026
5
- description: Discover how to make your Vite and Vue website multilingual. Follow the documentation to internationalize (i18n) and translate it.
3
+ updatedAt: 2026-05-31
4
+ title: Vite + Vue i18n - Complete guide to translate a Vue app
5
+ description: Optimized solution for bundle size, SEO, performances & maintainability. Make your Vite + Vue application multilingual in 2026, LLM translation, Agent Skills & MCP.
6
6
  keywords:
7
7
  - Internationalization
8
8
  - Documentation
@@ -17,6 +17,9 @@ slugs:
17
17
  - content
18
18
  - markdown
19
19
  history:
20
+ - version: 8.11.0
21
+ date: 2026-05-28
22
+ changes: "Allow pre parsing of Markdown ast parsing for SSR / hydration"
20
23
  - version: 8.10.0
21
24
  date: 2026-05-19
22
25
  changes: "Added support for `.content.md` files"
@@ -1152,6 +1155,164 @@ export class MyComponent {
1152
1155
 
1153
1156
  ---
1154
1157
 
1158
+ ## Server-Side Rendering (SSR) and Hydration
1159
+
1160
+ In comparison of other Markdown parser such as remark / rehype, the Intlayer Markdown is dependency free and run on client as server side.
1161
+
1162
+ But Intlayer optimized the parsing for Server-Side Rendering (SSR) frameworks (such as Next.js App Router, React Router, Nuxt, SvelteKit, etc.).
1163
+
1164
+ Instead of sending raw Markdown strings to the client and parsing them on the browser (which incurs a performance penalty), Intlayer allows you to pre-parse the Markdown into an Abstract Syntax Tree (AST) on the server.
1165
+
1166
+ You can use the `parseMarkdown` function from your framework's Intlayer package on the server side to generate a serializable AST (`ParsedMarkdown` object), and pass it directly to the frontend. All Intlayer rendering utilities (like `<MarkdownRenderer>`, `useMarkdownRenderer`, etc.) automatically accept this AST object and render it seamlessly.
1167
+
1168
+ ### Example in a Server/Client Architecture
1169
+
1170
+ <Tabs group="framework">
1171
+ <Tab label="React Router" value="react">
1172
+
1173
+ ```tsx fileName="server.ts"
1174
+ import { parseMarkdown } from "react-intlayer/markdown";
1175
+
1176
+ // 1. On the server: Parse the markdown into a serializable AST
1177
+ export const loader = async () => {
1178
+ const markdownString = "## My title \n\nLorem Ipsum";
1179
+ const ast = parseMarkdown(markdownString);
1180
+
1181
+ // Return the AST as JSON to the client
1182
+ return Response.json({ content: ast });
1183
+ };
1184
+ ```
1185
+
1186
+ ```tsx fileName="client.tsx"
1187
+ import { useLoaderData } from "react-router";
1188
+ import { MarkdownRenderer } from "react-intlayer/markdown";
1189
+
1190
+ // 2. On the client: Render the AST directly without re-parsing
1191
+ export default function Page() {
1192
+ const { content } = useLoaderData();
1193
+
1194
+ // The renderer accepts either a raw string or the parsed AST
1195
+ return <MarkdownRenderer content={content} />;
1196
+ }
1197
+ ```
1198
+
1199
+ </Tab>
1200
+ <Tab label="Next.js" value="nextjs">
1201
+
1202
+ ```tsx fileName="app/page.tsx"
1203
+ import { parseMarkdown } from "next-intlayer/markdown";
1204
+ import { MarkdownRenderer } from "next-intlayer/markdown";
1205
+
1206
+ export default async function Page() {
1207
+ // 1. Parse the markdown into a serializable AST on the server
1208
+ const markdownString = "## My title \n\nLorem Ipsum";
1209
+ const ast = parseMarkdown(markdownString);
1210
+
1211
+ // 2. Render the AST directly
1212
+ // In a Server Component, this works seamlessly and passes the AST
1213
+ // directly to the underlying client components if needed.
1214
+ return <MarkdownRenderer content={ast} />;
1215
+ }
1216
+ ```
1217
+
1218
+ </Tab>
1219
+ <Tab label="Vue / Nuxt" value="vue">
1220
+
1221
+ ```vue fileName="pages/index.vue"
1222
+ <script setup lang="ts">
1223
+ import { parseMarkdown } from "vue-intlayer/markdown";
1224
+ import { MarkdownRenderer } from "vue-intlayer/markdown";
1225
+
1226
+ // 1. Fetch and parse the markdown into an AST on the server
1227
+ const { data: ast } = await useAsyncData('markdown', () => {
1228
+ const markdownString = "## My title \n\nLorem Ipsum";
1229
+ return parseMarkdown(markdownString);
1230
+ });
1231
+ </script>
1232
+
1233
+ <template>
1234
+ <!-- 2. On the client: Render the AST directly without re-parsing -->
1235
+ <MarkdownRenderer :content="ast" />
1236
+ </template>
1237
+ ```
1238
+
1239
+ </Tab>
1240
+ <Tab label="SvelteKit" value="svelte">
1241
+
1242
+ ```typescript fileName="+page.server.ts"
1243
+ import { parseMarkdown } from "svelte-intlayer/markdown";
1244
+
1245
+ // 1. On the server: Parse the markdown into a serializable AST
1246
+ export const load = async () => {
1247
+ const markdownString = "## My title \n\nLorem Ipsum";
1248
+ const ast = parseMarkdown(markdownString);
1249
+
1250
+ // Return the AST to the client
1251
+ return { content: ast };
1252
+ };
1253
+ ```
1254
+
1255
+ ```svelte fileName="+page.svelte"
1256
+ <script lang="ts">
1257
+ import { MarkdownRenderer } from "svelte-intlayer/markdown";
1258
+ export let data;
1259
+ </script>
1260
+
1261
+ <!-- 2. On the client: Render the AST directly without re-parsing -->
1262
+ <MarkdownRenderer value={data.content} />
1263
+ ```
1264
+
1265
+ </Tab>
1266
+ <Tab label="Angular" value="angular">
1267
+
1268
+ Angular SSR typically resolves the data on the server during the initial load and hydrates on the client. You can use resolvers to pass the AST.
1269
+
1270
+ ```typescript fileName="app.resolver.ts"
1271
+ import { Injectable } from "@angular/core";
1272
+ import { Resolve } from "@angular/router";
1273
+ import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";
1274
+
1275
+ @Injectable({ providedIn: "root" })
1276
+ export class MarkdownResolver implements Resolve<ParsedMarkdown> {
1277
+ resolve(): ParsedMarkdown {
1278
+ const markdownString = "## My title \n\nLorem Ipsum";
1279
+ // 1. On the server: Parse the markdown into a serializable AST
1280
+ return parseMarkdown(markdownString);
1281
+ }
1282
+ }
1283
+ ```
1284
+
1285
+ ```typescript fileName="app.component.ts"
1286
+ import { Component } from "@angular/core";
1287
+ import { ActivatedRoute } from "@angular/router";
1288
+ import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";
1289
+
1290
+ @Component({
1291
+ selector: "app-root",
1292
+ template: `<div [innerHTML]="renderedMarkdown"></div>`,
1293
+ })
1294
+ export class AppComponent {
1295
+ renderedMarkdown: string = "";
1296
+
1297
+ constructor(
1298
+ private route: ActivatedRoute,
1299
+ private markdownService: IntlayerMarkdownService
1300
+ ) {
1301
+ // 2. On the client: Render the AST directly without re-parsing
1302
+ this.route.data.subscribe((data) => {
1303
+ this.renderedMarkdown = this.markdownService.renderMarkdown(
1304
+ data.markdownAst
1305
+ ) as string;
1306
+ });
1307
+ }
1308
+ }
1309
+ ```
1310
+
1311
+ </Tab>
1312
+ </Tabs>
1313
+
1314
+ This pattern ensures that the Markdown parsing logic is executed entirely on the server, significantly reducing the client-side execution time and improving the initial hydration speed.
1315
+
1155
1316
  ## Options Reference
1156
1317
 
1157
1318
  These options can be passed to `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer`, and `renderMarkdown`.
@@ -17,6 +17,9 @@ slugs:
17
17
  - content
18
18
  - markdown
19
19
  history:
20
+ - version: 8.11.0
21
+ date: 2026-05-28
22
+ changes: "Permitir el preanálisis del AST de Markdown para SSR / hidratación"
20
23
  - version: 8.10.0
21
24
  date: 2026-05-19
22
25
  changes: "Se agregó soporte para archivos `.content.md`"
@@ -1149,6 +1152,164 @@ export class MyComponent {
1149
1152
 
1150
1153
  ---
1151
1154
 
1155
+ ## Renderizado en el Lado del Servidor (SSR) e Hidratación
1156
+
1157
+ En comparación con otros analizadores de Markdown como remark / rehype, Intlayer Markdown no tiene dependencias y se ejecuta tanto en el cliente como en el servidor.
1158
+
1159
+ Sin embargo, Intlayer optimiza el análisis para frameworks de renderizado en el lado del servidor (SSR) (como Next.js App Router, React Router, Nuxt, SvelteKit, etc.).
1160
+
1161
+ En lugar de enviar cadenas Markdown crudas al cliente y analizarlas en el navegador (lo que incurre en una penalización de rendimiento), Intlayer le permite preanalizar el Markdown en un Árbol de Sintaxis Abstracta (AST) en el servidor.
1162
+
1163
+ Puede usar la función `parseMarkdown` del paquete Intlayer de su framework en el lado del servidor para generar un AST serializable (objeto `ParsedMarkdown`) y pasarlo directamente al frontend. Todas las utilidades de renderizado de Intlayer (como `<MarkdownRenderer>`, `useMarkdownRenderer`, etc.) aceptan automáticamente este objeto AST y lo renderizan sin problemas.
1164
+
1165
+ ### Ejemplo en una Arquitectura Servidor/Cliente
1166
+
1167
+ <Tabs group="framework">
1168
+ <Tab label="React Router" value="react">
1169
+
1170
+ ```tsx fileName="server.ts"
1171
+ import { parseMarkdown } from "react-intlayer/markdown";
1172
+
1173
+ // 1. En el servidor: Analizar el markdown en un AST serializable
1174
+ export const loader = async () => {
1175
+ const markdownString = "## My title \n\nLorem Ipsum";
1176
+ const ast = parseMarkdown(markdownString);
1177
+
1178
+ // Devolver el AST como JSON al cliente
1179
+ return Response.json({ content: ast });
1180
+ };
1181
+ ```
1182
+
1183
+ ```tsx fileName="client.tsx"
1184
+ import { useLoaderData } from "react-router";
1185
+ import { MarkdownRenderer } from "react-intlayer/markdown";
1186
+
1187
+ // 2. En el cliente: Renderizar el AST directamente sin volver a analizar
1188
+ export default function Page() {
1189
+ const { content } = useLoaderData();
1190
+
1191
+ // El renderizador acepta tanto una cadena cruda como el AST analizado
1192
+ return <MarkdownRenderer content={content} />;
1193
+ }
1194
+ ```
1195
+
1196
+ </Tab>
1197
+ <Tab label="Next.js" value="nextjs">
1198
+
1199
+ ```tsx fileName="app/page.tsx"
1200
+ import { parseMarkdown } from "next-intlayer/markdown";
1201
+ import { MarkdownRenderer } from "next-intlayer/markdown";
1202
+
1203
+ export default async function Page() {
1204
+ // 1. Analizar el markdown en un AST serializable en el servidor
1205
+ const markdownString = "## My title \n\nLorem Ipsum";
1206
+ const ast = parseMarkdown(markdownString);
1207
+
1208
+ // 2. Renderizar el AST directamente
1209
+ // En un Componente de Servidor, esto funciona sin problemas y pasa el AST
1210
+ // directamente a los componentes de cliente subyacentes si es necesario.
1211
+ return <MarkdownRenderer content={ast} />;
1212
+ }
1213
+ ```
1214
+
1215
+ </Tab>
1216
+ <Tab label="Vue / Nuxt" value="vue">
1217
+
1218
+ ```vue fileName="pages/index.vue"
1219
+ <script setup lang="ts">
1220
+ import { parseMarkdown } from "vue-intlayer/markdown";
1221
+ import { MarkdownRenderer } from "vue-intlayer/markdown";
1222
+
1223
+ // 1. Obtener y analizar el markdown en un AST en el servidor
1224
+ const { data: ast } = await useAsyncData('markdown', () => {
1225
+ const markdownString = "## My title \n\nLorem Ipsum";
1226
+ return parseMarkdown(markdownString);
1227
+ });
1228
+ </script>
1229
+
1230
+ <template>
1231
+ <!-- 2. En el cliente: Renderizar el AST directamente sin volver a analizar -->
1232
+ <MarkdownRenderer :content="ast" />
1233
+ </template>
1234
+ ```
1235
+
1236
+ </Tab>
1237
+ <Tab label="SvelteKit" value="svelte">
1238
+
1239
+ ```typescript fileName="+page.server.ts"
1240
+ import { parseMarkdown } from "svelte-intlayer/markdown";
1241
+
1242
+ // 1. En el servidor: Analizar el markdown en un AST serializable
1243
+ export const load = async () => {
1244
+ const markdownString = "## My title \n\nLorem Ipsum";
1245
+ const ast = parseMarkdown(markdownString);
1246
+
1247
+ // Devolver el AST al cliente
1248
+ return { content: ast };
1249
+ };
1250
+ ```
1251
+
1252
+ ```svelte fileName="+page.svelte"
1253
+ <script lang="ts">
1254
+ import { MarkdownRenderer } from "svelte-intlayer/markdown";
1255
+ export let data;
1256
+ </script>
1257
+
1258
+ <!-- 2. En el cliente: Renderizar el AST directamente sin volver a analizar -->
1259
+ <MarkdownRenderer value={data.content} />
1260
+ ```
1261
+
1262
+ </Tab>
1263
+ <Tab label="Angular" value="angular">
1264
+
1265
+ El SSR de Angular normalmente resuelve los datos en el servidor durante la carga inicial y se hidrata en el cliente. Puede usar solucionadores para pasar el AST.
1266
+
1267
+ ```typescript fileName="app.resolver.ts"
1268
+ import { Injectable } from "@angular/core";
1269
+ import { Resolve } from "@angular/router";
1270
+ import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";
1271
+
1272
+ @Injectable({ providedIn: "root" })
1273
+ export class MarkdownResolver implements Resolve<ParsedMarkdown> {
1274
+ resolve(): ParsedMarkdown {
1275
+ const markdownString = "## My title \n\nLorem Ipsum";
1276
+ // 1. En el servidor: Analizar el markdown en un AST serializable
1277
+ return parseMarkdown(markdownString);
1278
+ }
1279
+ }
1280
+ ```
1281
+
1282
+ ```typescript fileName="app.component.ts"
1283
+ import { Component } from "@angular/core";
1284
+ import { ActivatedRoute } from "@angular/router";
1285
+ import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";
1286
+
1287
+ @Component({
1288
+ selector: "app-root",
1289
+ template: `<div [innerHTML]="renderedMarkdown"></div>`,
1290
+ })
1291
+ export class AppComponent {
1292
+ renderedMarkdown: string = "";
1293
+
1294
+ constructor(
1295
+ private route: ActivatedRoute,
1296
+ private markdownService: IntlayerMarkdownService
1297
+ ) {
1298
+ // 2. En el cliente: Renderizar el AST directamente sin volver a analizar
1299
+ this.route.data.subscribe((data) => {
1300
+ this.renderedMarkdown = this.markdownService.renderMarkdown(
1301
+ data.markdownAst
1302
+ ) as string;
1303
+ });
1304
+ }
1305
+ }
1306
+ ```
1307
+
1308
+ </Tab>
1309
+ </Tabs>
1310
+
1311
+ Este patrón garantiza que la lógica de análisis de Markdown se ejecute completamente en el servidor, lo que reduce significativamente el tiempo de ejecución en el cliente y mejora la velocidad de hidratación inicial.
1312
+
1152
1313
  ## Referencia de opciones
1153
1314
 
1154
1315
  Estas opciones se pueden pasar a `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` y `renderMarkdown`.
@@ -17,6 +17,9 @@ slugs:
17
17
  - content
18
18
  - markdown
19
19
  history:
20
+ - version: 8.11.0
21
+ date: 2026-05-28
22
+ changes: "Permettre la pré-analyse de l'AST Markdown pour le SSR / l'hydratation"
20
23
  - version: 8.10.0
21
24
  date: 2026-05-19
22
25
  changes: "Ajout de la prise en charge des fichiers `.content.md`"
@@ -1149,6 +1152,164 @@ export class MyComponent {
1149
1152
 
1150
1153
  ---
1151
1154
 
1155
+ ## Rendu Côté Serveur (SSR) et Hydratation
1156
+
1157
+ 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.
1158
+
1159
+ 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.).
1160
+
1161
+ 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.
1162
+
1163
+ 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.
1164
+
1165
+ ### Exemple dans une architecture Serveur/Client
1166
+
1167
+ <Tabs group="framework">
1168
+ <Tab label="React Router" value="react">
1169
+
1170
+ ```tsx fileName="server.ts"
1171
+ import { parseMarkdown } from "react-intlayer/markdown";
1172
+
1173
+ // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
1174
+ export const loader = async () => {
1175
+ const markdownString = "## My title \n\nLorem Ipsum";
1176
+ const ast = parseMarkdown(markdownString);
1177
+
1178
+ // Renvoyer l'AST au client sous forme de JSON
1179
+ return Response.json({ content: ast });
1180
+ };
1181
+ ```
1182
+
1183
+ ```tsx fileName="client.tsx"
1184
+ import { useLoaderData } from "react-router";
1185
+ import { MarkdownRenderer } from "react-intlayer/markdown";
1186
+
1187
+ // 2. Sur le client : Rendre l'AST directement sans ré-analyse
1188
+ export default function Page() {
1189
+ const { content } = useLoaderData();
1190
+
1191
+ // Le renderer accepte soit une chaîne brute, soit l'AST analysé
1192
+ return <MarkdownRenderer content={content} />;
1193
+ }
1194
+ ```
1195
+
1196
+ </Tab>
1197
+ <Tab label="Next.js" value="nextjs">
1198
+
1199
+ ```tsx fileName="app/page.tsx"
1200
+ import { parseMarkdown } from "next-intlayer/markdown";
1201
+ import { MarkdownRenderer } from "next-intlayer/markdown";
1202
+
1203
+ export default async function Page() {
1204
+ // 1. Analyser le markdown en un AST sérialisable sur le serveur
1205
+ const markdownString = "## My title \n\nLorem Ipsum";
1206
+ const ast = parseMarkdown(markdownString);
1207
+
1208
+ // 2. Rendre l'AST directement
1209
+ // Dans un composant serveur, cela fonctionne de manière transparente et transmet l'AST
1210
+ // directement aux composants clients sous-jacents si nécessaire.
1211
+ return <MarkdownRenderer content={ast} />;
1212
+ }
1213
+ ```
1214
+
1215
+ </Tab>
1216
+ <Tab label="Vue / Nuxt" value="vue">
1217
+
1218
+ ```vue fileName="pages/index.vue"
1219
+ <script setup lang="ts">
1220
+ import { parseMarkdown } from "vue-intlayer/markdown";
1221
+ import { MarkdownRenderer } from "vue-intlayer/markdown";
1222
+
1223
+ // 1. Récupérer et analyser le markdown en un AST sur le serveur
1224
+ const { data: ast } = await useAsyncData('markdown', () => {
1225
+ const markdownString = "## My title \n\nLorem Ipsum";
1226
+ return parseMarkdown(markdownString);
1227
+ });
1228
+ </script>
1229
+
1230
+ <template>
1231
+ <!-- 2. Sur le client : Rendre l'AST directement sans ré-analyse -->
1232
+ <MarkdownRenderer :content="ast" />
1233
+ </template>
1234
+ ```
1235
+
1236
+ </Tab>
1237
+ <Tab label="SvelteKit" value="svelte">
1238
+
1239
+ ```typescript fileName="+page.server.ts"
1240
+ import { parseMarkdown } from "svelte-intlayer/markdown";
1241
+
1242
+ // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
1243
+ export const load = async () => {
1244
+ const markdownString = "## My title \n\nLorem Ipsum";
1245
+ const ast = parseMarkdown(markdownString);
1246
+
1247
+ // Renvoyer l'AST au client
1248
+ return { content: ast };
1249
+ };
1250
+ ```
1251
+
1252
+ ```svelte fileName="+page.svelte"
1253
+ <script lang="ts">
1254
+ import { MarkdownRenderer } from "svelte-intlayer/markdown";
1255
+ export let data;
1256
+ </script>
1257
+
1258
+ <!-- 2. Sur le client : Rendre l'AST directement sans ré-analyse -->
1259
+ <MarkdownRenderer value={data.content} />
1260
+ ```
1261
+
1262
+ </Tab>
1263
+ <Tab label="Angular" value="angular">
1264
+
1265
+ 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.
1266
+
1267
+ ```typescript fileName="app.resolver.ts"
1268
+ import { Injectable } from "@angular/core";
1269
+ import { Resolve } from "@angular/router";
1270
+ import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";
1271
+
1272
+ @Injectable({ providedIn: "root" })
1273
+ export class MarkdownResolver implements Resolve<ParsedMarkdown> {
1274
+ resolve(): ParsedMarkdown {
1275
+ const markdownString = "## My title \n\nLorem Ipsum";
1276
+ // 1. Sur le serveur : Analyser le markdown en un AST sérialisable
1277
+ return parseMarkdown(markdownString);
1278
+ }
1279
+ }
1280
+ ```
1281
+
1282
+ ```typescript fileName="app.component.ts"
1283
+ import { Component } from "@angular/core";
1284
+ import { ActivatedRoute } from "@angular/router";
1285
+ import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";
1286
+
1287
+ @Component({
1288
+ selector: "app-root",
1289
+ template: `<div [innerHTML]="renderedMarkdown"></div>`,
1290
+ })
1291
+ export class AppComponent {
1292
+ renderedMarkdown: string = "";
1293
+
1294
+ constructor(
1295
+ private route: ActivatedRoute,
1296
+ private markdownService: IntlayerMarkdownService
1297
+ ) {
1298
+ // 2. Sur le client : Rendre l'AST directement sans ré-analyse
1299
+ this.route.data.subscribe((data) => {
1300
+ this.renderedMarkdown = this.markdownService.renderMarkdown(
1301
+ data.markdownAst
1302
+ ) as string;
1303
+ });
1304
+ }
1305
+ }
1306
+ ```
1307
+
1308
+ </Tab>
1309
+ </Tabs>
1310
+
1311
+ 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.
1312
+
1152
1313
  ## Référence des options
1153
1314
 
1154
1315
  Ces options peuvent être passées à `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` et `renderMarkdown`.