@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.
- package/blog/en/i18n_using_next-i18next.md +3 -3
- package/blog/en/i18n_using_next-intl.md +3 -3
- package/blog/en/list_i18n_technologies/frameworks/angular.md +3 -3
- package/blog/en/list_i18n_technologies/frameworks/react-native.md +3 -3
- package/blog/en/list_i18n_technologies/frameworks/react.md +3 -3
- package/blog/en/list_i18n_technologies/frameworks/svelte.md +3 -3
- package/blog/en/list_i18n_technologies/frameworks/vue.md +3 -3
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +3 -3
- package/dist/cjs/generated/blog.entry.cjs +0 -1
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +0 -1
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +0 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +0 -1
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/docs/ar/dictionary/markdown.md +161 -0
- package/docs/de/dictionary/markdown.md +161 -0
- package/docs/en/dictionary/markdown.md +163 -0
- package/docs/en/intlayer_with_adonisjs.md +3 -3
- package/docs/en/intlayer_with_analog.md +3 -3
- package/docs/en/intlayer_with_angular_19.md +3 -3
- package/docs/en/intlayer_with_angular_21.md +3 -3
- package/docs/en/intlayer_with_astro.md +3 -3
- package/docs/en/intlayer_with_astro_lit.md +3 -3
- package/docs/en/intlayer_with_astro_preact.md +3 -3
- package/docs/en/intlayer_with_astro_react.md +3 -3
- package/docs/en/intlayer_with_astro_solid.md +3 -3
- package/docs/en/intlayer_with_astro_svelte.md +3 -3
- package/docs/en/intlayer_with_astro_vanilla.md +3 -3
- package/docs/en/intlayer_with_astro_vue.md +3 -3
- package/docs/en/intlayer_with_create_react_app.md +3 -3
- package/docs/en/intlayer_with_express.md +3 -3
- package/docs/en/intlayer_with_fastify.md +3 -3
- package/docs/en/intlayer_with_hono.md +3 -3
- package/docs/en/intlayer_with_lynx+react.md +3 -3
- package/docs/en/intlayer_with_nestjs.md +3 -3
- package/docs/en/intlayer_with_next-i18next.md +3 -3
- package/docs/en/intlayer_with_next-intl.md +3 -3
- package/docs/en/intlayer_with_nextjs_14.md +3 -3
- package/docs/en/intlayer_with_nextjs_15.md +3 -3
- package/docs/en/intlayer_with_nextjs_16.md +3 -3
- package/docs/en/intlayer_with_nextjs_compiler.md +3 -3
- package/docs/en/intlayer_with_nextjs_no_locale_path.md +3 -3
- package/docs/en/intlayer_with_nextjs_page_router.md +3 -3
- package/docs/en/intlayer_with_nuxt.md +3 -3
- package/docs/en/intlayer_with_react_native+expo.md +3 -3
- package/docs/en/intlayer_with_react_router_v7.md +3 -3
- package/docs/en/intlayer_with_react_router_v7_fs_routes.md +3 -3
- package/docs/en/intlayer_with_svelte_kit.md +3 -3
- package/docs/en/intlayer_with_tanstack+solid.md +3 -3
- package/docs/en/intlayer_with_tanstack.md +3 -3
- package/docs/en/intlayer_with_vanilla.md +3 -3
- package/docs/en/intlayer_with_vite+lit.md +3 -3
- package/docs/en/intlayer_with_vite+preact.md +3 -3
- package/docs/en/intlayer_with_vite+react.md +3 -3
- package/docs/en/intlayer_with_vite+react_compiler.md +3 -3
- package/docs/en/intlayer_with_vite+solid.md +3 -3
- package/docs/en/intlayer_with_vite+svelte.md +3 -3
- package/docs/en/intlayer_with_vite+vanilla.md +3 -3
- package/docs/en/intlayer_with_vite+vue.md +3 -3
- package/docs/en-GB/dictionary/markdown.md +161 -0
- package/docs/es/dictionary/markdown.md +161 -0
- package/docs/fr/dictionary/markdown.md +161 -0
- package/docs/hi/dictionary/markdown.md +161 -0
- package/docs/id/dictionary/markdown.md +161 -0
- package/docs/it/dictionary/markdown.md +161 -0
- package/docs/ko/dictionary/markdown.md +161 -0
- package/docs/pl/dictionary/markdown.md +161 -0
- package/docs/pt/dictionary/markdown.md +161 -0
- package/docs/ru/dictionary/markdown.md +161 -0
- package/docs/tr/dictionary/markdown.md +161 -0
- package/docs/uk/dictionary/markdown.md +161 -0
- package/docs/vi/dictionary/markdown.md +161 -0
- package/docs/zh/dictionary/markdown.md +161 -0
- package/package.json +7 -7
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2026-03-31
|
|
3
|
-
updatedAt: 2026-05-
|
|
4
|
-
title: Vanilla JS i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Lit i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Preact i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + React i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + React i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Solid i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Svelte i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Vanilla JS i18n -
|
|
5
|
-
description:
|
|
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-
|
|
4
|
-
title: Vite + Vue i18n -
|
|
5
|
-
description:
|
|
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`.
|