@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
@@ -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: "Cho phép phân tích cú pháp trước AST Markdown cho SSR / hydrat hóa"
20
23
  - version: 8.10.0
21
24
  date: 2026-05-19
22
25
  changes: "Thêm hỗ trợ cho các tệp `.content.md`"
@@ -1149,6 +1152,164 @@ export class MyComponent {
1149
1152
 
1150
1153
  ---
1151
1154
 
1155
+ ## Render Phía Server (SSR) và Hydrat Hóa
1156
+
1157
+ So với các trình phân tích cú pháp Markdown khác như remark / rehype, Intlayer Markdown không phụ thuộc và chạy trên cả client lẫn server.
1158
+
1159
+ Nhưng Intlayer tối ưu hóa việc phân tích cú pháp cho các framework Server-Side Rendering (SSR) (như Next.js App Router, React Router, Nuxt, SvelteKit, v.v.).
1160
+
1161
+ Thay vì gửi chuỗi Markdown thô đến client và phân tích cú pháp trên trình duyệt (gây giảm hiệu suất), Intlayer cho phép bạn phân tích cú pháp trước Markdown thành Cây Cú Pháp Trừu Tượng (AST) trên server.
1162
+
1163
+ Bạn có thể sử dụng hàm `parseMarkdown` từ gói Intlayer của framework phía server để tạo ra một AST có thể tuần tự hóa (đối tượng `ParsedMarkdown`), và chuyển trực tiếp đến frontend. Tất cả các tiện ích render của Intlayer (như `<MarkdownRenderer>`, `useMarkdownRenderer`, v.v.) tự động chấp nhận đối tượng AST này và hiển thị nó một cách liền mạch.
1164
+
1165
+ ### Ví dụ trong Kiến Trúc Server/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. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa
1174
+ export const loader = async () => {
1175
+ const markdownString = "## My title \n\nLorem Ipsum";
1176
+ const ast = parseMarkdown(markdownString);
1177
+
1178
+ // Trả về AST dưới dạng JSON cho client
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. Trên client: Hiển thị trực tiếp AST mà không cần phân tích cú pháp lại
1188
+ export default function Page() {
1189
+ const { content } = useLoaderData();
1190
+
1191
+ // Trình kết xuất chấp nhận chuỗi thô hoặc AST đã được phân tích cú pháp
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. Phân tích cú pháp markdown thành AST có thể tuần tự hóa trên server
1205
+ const markdownString = "## My title \n\nLorem Ipsum";
1206
+ const ast = parseMarkdown(markdownString);
1207
+
1208
+ // 2. Hiển thị trực tiếp AST
1209
+ // Trong một Server Component, hoạt động này diễn ra liền mạch và chuyển AST
1210
+ // trực tiếp đến các client component bên dưới nếu cần.
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. Lấy và phân tích cú pháp markdown thành AST trên server
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. Trên client: Hiển thị trực tiếp AST mà không cần phân tích cú pháp lại -->
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. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa
1243
+ export const load = async () => {
1244
+ const markdownString = "## My title \n\nLorem Ipsum";
1245
+ const ast = parseMarkdown(markdownString);
1246
+
1247
+ // Trả về AST cho 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. Trên client: Hiển thị trực tiếp AST mà không cần phân tích cú pháp lại -->
1259
+ <MarkdownRenderer value={data.content} />
1260
+ ```
1261
+
1262
+ </Tab>
1263
+ <Tab label="Angular" value="angular">
1264
+
1265
+ Angular SSR thường giải quyết dữ liệu trên server trong lần tải đầu tiên và hydrat hóa trên client. Bạn có thể sử dụng resolver để truyền 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. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa
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. Trên client: Hiển thị trực tiếp AST mà không cần phân tích cú pháp lại
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
+ Mẫu này đảm bảo logic phân tích cú pháp Markdown được thực thi hoàn toàn trên server, giảm đáng kể thời gian thực thi phía client và cải thiện tốc độ hydrat hóa ban đầu.
1312
+
1152
1313
  ## Tham chiếu tùy chọn
1153
1314
 
1154
1315
  Các tùy chọn này có thể được truyền đến `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` và `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: "允许为 SSR / 注水(hydration)预解析 Markdown AST"
20
23
  - version: 8.10.0
21
24
  date: 2026-05-19
22
25
  changes: "添加对 `.content.md` 文件的支持"
@@ -1149,6 +1152,164 @@ export class MyComponent {
1149
1152
 
1150
1153
  ---
1151
1154
 
1155
+ ## 服务端渲染 (SSR) 与 注水 (Hydration)
1156
+
1157
+ 与其他 Markdown 解析器(如 remark / rehype)相比,Intlayer Markdown 无依赖关系,且既可以在客户端运行,也可以在服务端运行。
1158
+
1159
+ 但是 Intlayer 针对服务端渲染 (SSR) 框架(如 Next.js App Router, React Router, Nuxt, SvelteKit 等)进行了解析优化。
1160
+
1161
+ Intlayer 允许您在服务端将 Markdown 预解析为抽象语法树 (AST),而不是将原始 Markdown 字符串发送到客户端并在浏览器中解析(这会带来性能损失)。
1162
+
1163
+ 您可以在服务端使用框架的 Intlayer 包中的 `parseMarkdown` 函数来生成可序列化的 AST(`ParsedMarkdown` 对象),并将其直接传递给前端。所有 Intlayer 渲染工具(如 `<MarkdownRenderer>`、`useMarkdownRenderer` 等)都会自动接受此 AST 对象并无缝渲染它。
1164
+
1165
+ ### 服务端/客户端架构中的示例
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. 在服务端:将 markdown 解析为可序列化的 AST
1174
+ export const loader = async () => {
1175
+ const markdownString = "## My title \n\nLorem Ipsum";
1176
+ const ast = parseMarkdown(markdownString);
1177
+
1178
+ // 将 AST 作为 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. 在客户端:直接渲染 AST,无需重新解析
1188
+ export default function Page() {
1189
+ const { content } = useLoaderData();
1190
+
1191
+ // 渲染器既接受原始字符串,也接受解析后的 AST
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. 在服务端将 markdown 解析为可序列化的 AST
1205
+ const markdownString = "## My title \n\nLorem Ipsum";
1206
+ const ast = parseMarkdown(markdownString);
1207
+
1208
+ // 2. 直接渲染 AST
1209
+ // 在服务端组件(Server Component)中,这可以无缝工作,并在需要时
1210
+ // 直接将 AST 传递给底层的客户端组件。
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. 在服务端获取并解析 markdown 为 AST
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. 在客户端:直接渲染 AST,无需重新解析 -->
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. 在服务端:将 markdown 解析为可序列化的 AST
1243
+ export const load = async () => {
1244
+ const markdownString = "## My title \n\nLorem Ipsum";
1245
+ const ast = parseMarkdown(markdownString);
1246
+
1247
+ // 将 AST 返回给客户端
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. 在客户端:直接渲染 AST,无需重新解析 -->
1259
+ <MarkdownRenderer value={data.content} />
1260
+ ```
1261
+
1262
+ </Tab>
1263
+ <Tab label="Angular" value="angular">
1264
+
1265
+ Angular SSR 通常在初始加载期间在服务端解析数据,并在客户端进行注水。您可以使用解析器(resolvers)来传递 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. 在服务端:将 markdown 解析为可序列化的 AST
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. 在客户端:直接渲染 AST,无需重新解析
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
+ 这种模式确保 Markdown 解析逻辑完全在服务端执行,从而显著减少客户端执行时间,并提高初始注水速度。
1312
+
1152
1313
  ## 选项参考
1153
1314
 
1154
1315
  这些选项可传递给`MarkdownProvider`、`MarkdownRenderer`、`useMarkdownRenderer`和`renderMarkdown`。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/docs",
3
- "version": "8.11.1",
3
+ "version": "8.11.2",
4
4
  "private": false,
5
5
  "description": "Intlayer documentation",
6
6
  "keywords": [
@@ -72,20 +72,20 @@
72
72
  "watch": "webpack --config ./webpack.config.ts --watch"
73
73
  },
74
74
  "dependencies": {
75
- "@intlayer/config": "8.11.1",
76
- "@intlayer/core": "8.11.1",
77
- "@intlayer/types": "8.11.1"
75
+ "@intlayer/config": "8.11.2",
76
+ "@intlayer/core": "8.11.2",
77
+ "@intlayer/types": "8.11.2"
78
78
  },
79
79
  "devDependencies": {
80
- "@intlayer/api": "8.11.1",
81
- "@intlayer/cli": "8.11.1",
80
+ "@intlayer/api": "8.11.2",
81
+ "@intlayer/cli": "8.11.2",
82
82
  "@types/node": "25.9.1",
83
83
  "@utils/ts-config": "1.0.4",
84
84
  "@utils/ts-config-types": "1.0.4",
85
85
  "@utils/tsdown-config": "1.0.4",
86
86
  "fast-glob": "3.3.3",
87
87
  "rimraf": "6.1.3",
88
- "tsdown": "0.22.00",
88
+ "tsdown": "0.22.1",
89
89
  "typescript": "6.0.3",
90
90
  "vitest": "4.1.7"
91
91
  },