@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
|
@@ -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 / हाइड्रेशन के लिए मार्कडाउन एएसटी के पूर्व-पार्सिंग की अनुमति दें"
|
|
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) और हाइड्रेशन
|
|
1156
|
+
|
|
1157
|
+
अन्य मार्कडाउन पार्सर जैसे remark / rehype की तुलना में, Intlayer Markdown पूरी तरह से निर्भरता-मुक्त है और क्लाइंट तथा सर्वर दोनों साइड पर चलता है।
|
|
1158
|
+
|
|
1159
|
+
लेकिन Intlayer ने सर्वर-साइड रेंडरिंग (SSR) फ्रेमवर्क (जैसे Next.js App Router, React Router, Nuxt, SvelteKit, आदि) के लिए पार्सिंग को अनुकूलित किया है।
|
|
1160
|
+
|
|
1161
|
+
क्लाइंट को रॉ मार्कडाउन स्ट्रिंग्स भेजने और ब्राउज़र पर उन्हें पार्स करने के बजाय (जिससे प्रदर्शन प्रभावित होता है), Intlayer आपको सर्वर पर ही मार्कडाउन को एब्सट्रैक्ट सिंटैक्स ट्री (AST) में प्री-पार्स करने की अनुमति देता है।
|
|
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. सर्वर पर: मार्कडाउन को एक सीरियलाइज़ेबल 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. सर्वर पर मार्कडाउन को सीरियलाइज़ेबल AST में पार्स करें
|
|
1205
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1206
|
+
const ast = parseMarkdown(markdownString);
|
|
1207
|
+
|
|
1208
|
+
// 2. सीधे AST को रेंडर करें
|
|
1209
|
+
// सर्वर कंपोनेंट में, यह बिना किसी समस्या के काम करता है और यदि आवश्यक हो
|
|
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. सर्वर पर मार्कडाउन प्राप्त करें और उसे 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. सर्वर पर: मार्कडाउन को एक सीरियलाइज़ेबल 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 आमतौर पर प्रारंभिक लोड के दौरान सर्वर पर डेटा हल करता है और क्लाइंट पर हाइड्रेट करता है। आप 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. सर्वर पर: मार्कडाउन को एक सीरियलाइज़ेबल 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
|
+
यह पैटर्न यह सुनिश्चित करता है कि मार्कडाउन पार्सिंग लॉजिक पूरी तरह से सर्वर पर निष्पादित हो, जिससे क्लाइंट-साइड निष्पादन समय काफी कम हो जाता है और प्रारंभिक हाइड्रेशन गति में सुधार होता है।
|
|
1312
|
+
|
|
1152
1313
|
## विकल्प संदर्भ
|
|
1153
1314
|
|
|
1154
1315
|
इन विकल्पों को `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` और `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: "Mengizinkan pra-parsing AST Markdown untuk SSR / hidrasi"
|
|
20
23
|
- version: 8.10.0
|
|
21
24
|
date: 2026-05-19
|
|
22
25
|
changes: "Menambahkan dukungan untuk file `.content.md`"
|
|
@@ -1149,6 +1152,164 @@ export class MyComponent {
|
|
|
1149
1152
|
|
|
1150
1153
|
---
|
|
1151
1154
|
|
|
1155
|
+
## Rendering Sisi Server (SSR) dan Hidrasi
|
|
1156
|
+
|
|
1157
|
+
Dibandingkan dengan parser Markdown lainnya seperti remark / rehype, Intlayer Markdown bebas ketergantungan dan berjalan di sisi klien maupun server.
|
|
1158
|
+
|
|
1159
|
+
Namun Intlayer mengoptimalkan parsing untuk framework Server-Side Rendering (SSR) (seperti Next.js App Router, React Router, Nuxt, SvelteKit, dll.).
|
|
1160
|
+
|
|
1161
|
+
Hidrasi di browser memakan waktu, sehingga Intlayer memungkinkan Anda untuk mem-parsing Markdown terlebih dahulu ke dalam Abstract Syntax Tree (AST) di server, lalu mengirimkannya sebagai objek JSON yang dapat diserialisasi ke frontend.
|
|
1162
|
+
|
|
1163
|
+
Anda dapat menggunakan fungsi `parseMarkdown` dari paket Intlayer framework Anda di sisi server untuk menghasilkan AST yang dapat diserialisasi (objek `ParsedMarkdown`), dan meneruskannya secara langsung ke frontend. Semua utilitas rendering Intlayer (seperti `<MarkdownRenderer>`, `useMarkdownRenderer`, dll.) secara otomatis menerima objek AST ini dan merendernya dengan lancar.
|
|
1164
|
+
|
|
1165
|
+
### Contoh dalam Arsitektur Server/Klien
|
|
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. Di server: Parsing markdown ke dalam AST yang dapat diserialisasi
|
|
1174
|
+
export const loader = async () => {
|
|
1175
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1176
|
+
const ast = parseMarkdown(markdownString);
|
|
1177
|
+
|
|
1178
|
+
// Kembalikan AST sebagai JSON ke klien
|
|
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. Di klien: Render AST secara langsung tanpa mem-parsing ulang
|
|
1188
|
+
export default function Page() {
|
|
1189
|
+
const { content } = useLoaderData();
|
|
1190
|
+
|
|
1191
|
+
// Renderer menerima string mentah atau AST hasil parsing
|
|
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. Parsing markdown ke dalam AST yang dapat diserialisasi di server
|
|
1205
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1206
|
+
const ast = parseMarkdown(markdownString);
|
|
1207
|
+
|
|
1208
|
+
// 2. Render AST secara langsung
|
|
1209
|
+
// Dalam Server Component, ini bekerja dengan lancar dan meneruskan AST
|
|
1210
|
+
// secara langsung ke komponen klien di bawahnya jika diperlukan.
|
|
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. Ambil dan parsing markdown ke dalam AST di 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. Di klien: Render AST secara langsung tanpa mem-parsing ulang -->
|
|
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. Di server: Parsing markdown ke dalam AST yang dapat diserialisasi
|
|
1243
|
+
export const load = async () => {
|
|
1244
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1245
|
+
const ast = parseMarkdown(markdownString);
|
|
1246
|
+
|
|
1247
|
+
// Kembalikan AST ke klien
|
|
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. Di klien: Render AST secara langsung tanpa mem-parsing ulang -->
|
|
1259
|
+
<MarkdownRenderer value={data.content} />
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
</Tab>
|
|
1263
|
+
<Tab label="Angular" value="angular">
|
|
1264
|
+
|
|
1265
|
+
Angular SSR biasanya menyelesaikan data di server selama pemuatan awal dan menghidrasi di klien. Anda dapat menggunakan resolver untuk meneruskan 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. Di server: Parsing markdown ke dalam AST yang dapat diserialisasi
|
|
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. Di klien: Render AST secara langsung tanpa mem-parsing ulang
|
|
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
|
+
Pola ini memastikan bahwa logika parsing Markdown dieksekusi sepenuhnya di server, secara signifikan mengurangi waktu eksekusi di sisi klien dan meningkatkan kecepatan hidrasi awal.
|
|
1312
|
+
|
|
1152
1313
|
## Referensi Opsi
|
|
1153
1314
|
|
|
1154
1315
|
Opsi ini dapat diteruskan ke `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer`, dan `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: "Consenti la pre-analisi dell'AST Markdown per SSR / idratazione"
|
|
20
23
|
- version: 8.10.0
|
|
21
24
|
date: 2026-05-19
|
|
22
25
|
changes: "Aggiunto il supporto per i file `.content.md`"
|
|
@@ -1149,6 +1152,164 @@ export class MyComponent {
|
|
|
1149
1152
|
|
|
1150
1153
|
---
|
|
1151
1154
|
|
|
1155
|
+
## Rendering Lato Server (SSR) e Idratazione
|
|
1156
|
+
|
|
1157
|
+
Rispetto ad altri parser Markdown come remark / rehype, Intlayer Markdown è privo di dipendenze e viene eseguito sia sul client che sul server.
|
|
1158
|
+
|
|
1159
|
+
Tuttavia, Intlayer ottimizza l'analisi per i framework di rendering lato server (SSR) (come Next.js App Router, React Router, Nuxt, SvelteKit, ecc.).
|
|
1160
|
+
|
|
1161
|
+
Invece di inviare stringhe Markdown grezze al client e analizzarle nel browser (il che comporta una penalizzazione delle prestazioni), Intlayer consente di pre-analizzare il Markdown in un albero sintattico astratto (AST) sul server.
|
|
1162
|
+
|
|
1163
|
+
È possibile utilizzare la funzione `parseMarkdown` del pacchetto Intlayer del proprio framework lato server per generare un AST serializzabile (oggetto `ParsedMarkdown`) e passarlo direttamente al frontend. Tutte le utilità di rendering di Intlayer (come `<MarkdownRenderer>`, `useMarkdownRenderer`, ecc.) accettano automaticamente questo oggetto AST e lo renderizzano perfettamente.
|
|
1164
|
+
|
|
1165
|
+
### Esempio in un'Architettura 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. Sul server: Analizza il markdown in un AST serializzabile
|
|
1174
|
+
export const loader = async () => {
|
|
1175
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1176
|
+
const ast = parseMarkdown(markdownString);
|
|
1177
|
+
|
|
1178
|
+
// Restituisce l'AST come JSON al 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. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare
|
|
1188
|
+
export default function Page() {
|
|
1189
|
+
const { content } = useLoaderData();
|
|
1190
|
+
|
|
1191
|
+
// Il renderer accetta una stringa grezza o l'AST analizzato
|
|
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. Analizza il markdown in un AST serializzabile sul server
|
|
1205
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1206
|
+
const ast = parseMarkdown(markdownString);
|
|
1207
|
+
|
|
1208
|
+
// 2. Esegue il rendering dell'AST direttamente
|
|
1209
|
+
// In un Server Component, questo funziona perfettamente e passa l'AST
|
|
1210
|
+
// direttamente ai componenti client sottostanti se necessario.
|
|
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. Recupera e analizza il markdown in un AST sul 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. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare -->
|
|
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. Sul server: Analizza il markdown in un AST serializzabile
|
|
1243
|
+
export const load = async () => {
|
|
1244
|
+
const markdownString = "## My title \n\nLorem Ipsum";
|
|
1245
|
+
const ast = parseMarkdown(markdownString);
|
|
1246
|
+
|
|
1247
|
+
// Restituisce l'AST al 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. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare -->
|
|
1259
|
+
<MarkdownRenderer value={data.content} />
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
</Tab>
|
|
1263
|
+
<Tab label="Angular" value="angular">
|
|
1264
|
+
|
|
1265
|
+
L'SSR di Angular in genere risolve i dati sul server durante il caricamento iniziale e si idrata sul client. È possibile utilizzare i resolver per passare 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. Sul server: Analizza il markdown in un AST serializzabile
|
|
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. Sul client: Esegue il rendering dell'AST direttamente senza ri-analizzare
|
|
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
|
+
Questo modello garantisce che la logica di analisi del Markdown venga eseguita interamente sul server, riducendo significativamente il tempo di esecuzione lato client e migliorando la velocità di idratazione iniziale.
|
|
1312
|
+
|
|
1152
1313
|
## Riferimento opzioni
|
|
1153
1314
|
|
|
1154
1315
|
Queste opzioni possono essere passate a `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` e `renderMarkdown`.
|