\n\n \n \n \n ```\n\n Cấu hình toàn cục thông qua plugin `intlayerMarkdown` (hỗ trợ các component tùy chỉnh MDX):\n\n ```ts fileName=\"main.ts\"\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n\n app.use(intlayerMarkdown, {\n components: {\n h1: (props) => h('h1', { style: { color: 'green' } }, props.children),\n MyButton: (props) => h('button', props), // Component MDX\n },\n });\n ```\n\n > Nếu plugin `intlayerMarkdown` không được cài đặt, Intlayer sẽ render bằng trình biên dịch mặc định.\n\n Bạn cũng có thể cung cấp các ghi đè cục bộ cho các node cụ thể bằng phương thức `.use()`:\n\n ```vue\n h('h1', { style: { color: 'red' } }, props.children),\n })\" />\n ```\n\n Bạn có thể lấy Markdown dưới dạng chuỗi:\n\n ```vue\n {{ myMarkdownContent.value }}\n {{ String(myMarkdownContent) }}\n {{ myMarkdownContent.toString() }}\n ```\n\n Và bạn có thể truy cập siêu dữ liệu markdown của mình như sau:\n\n ```vue\n \n \n ```\n\n \n \n Svelte render Markdown thành một chuỗi HTML theo mặc định. Sử dụng `{@html}` để render nó.\n\n ```svelte fileName=\"App.svelte\"\n \n\n \n {@html $content.myMarkdownContent}\n \n ```\n\n > Nếu không có `MarkdownProvider`, Intlayer sẽ render markdown bằng trình biên dịch mặc định.\n\n Bạn cũng có thể cung cấp các ghi đè cục bộ cho các node cụ thể bằng phương thức `.use()`:\n\n ```svelte\n {@html $content.myMarkdownContent.use({ ... })}\n ```\n\n Bạn có thể lấy Markdown dưới dạng chuỗi:\n\n ```svelte\n {$content.myMarkdownContent.value}\n {String($content.myMarkdownContent)}\n {$content.myMarkdownContent.toString()}\n ```\n\n Và bạn có thể truy cập siêu dữ liệu markdown của mình như sau:\n\n ```svelte\n {$content.myMarkdownContent.metadata}\n {$content.myMarkdownContent.metadata.title}\n ```\n\n \n \n Preact hỗ trợ các node Markdown trực tiếp trong JSX.\n\n ```tsx fileName=\"App.tsx\"\n import { useIntlayer } from \"preact-intlayer\";\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n const AppContent = () => {\n const { myMarkdownContent } = useIntlayer(\"app\");\n return
{myMarkdownContent}
;\n };\n\n const App = () => (\n
{children}
,\n MyButton: (props) => , // Component MDX\n }}\n >\n \n \n );\n ```\n\n > Nếu không có `MarkdownProvider`, Intlayer sẽ render markdown bằng trình phân tích cú pháp Markdown sang JSX mặc định.\n\n Bạn cũng có thể cung cấp các ghi đè cục bộ cho các node cụ thể bằng phương thức `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: ({ children }) =>
{children}
,\n })}\n ```\n\n Bạn có thể lấy Markdown dưới dạng chuỗi:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Và bạn có thể truy cập siêu dữ liệu markdown của mình như sau:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Solid hỗ trợ các node Markdown trực tiếp trong JSX.\n\n ```tsx fileName=\"App.tsx\"\n import { useIntlayer } from \"solid-intlayer\";\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n const AppContent = () => {\n const { myMarkdownContent } = useIntlayer(\"app\");\n return
{myMarkdownContent}
;\n };\n\n const App = () => (\n
{props.children}
,\n MyButton: (props) => , // Component MDX\n }}\n >\n \n \n );\n ```\n\n > Nếu không có `MarkdownProvider`, Intlayer sẽ render markdown bằng trình phân tích cú pháp Markdown sang JSX mặc định.\n\n Bạn cũng có thể cung cấp các ghi đè cục bộ cho các node cụ thể bằng phương thức `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: (props) =>
{props.children}
,\n })}\n ```\n\n Bạn có thể lấy Markdown dưới dạng chuỗi:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Và bạn có thể truy cập siêu dữ liệu markdown của mình như sau:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Angular sử dụng chỉ thị `[innerHTML]` để render nội dung Markdown.\n\n ```typescript fileName=\"app.component.ts\"\n import { Component } from \"@angular/core\";\n import { useIntlayer } from \"angular-intlayer\";\n\n @Component({\n selector: \"app-root\",\n template: ``,\n })\n export class AppComponent {\n content = useIntlayer(\"app\");\n }\n ```\n\n > Nếu provider IntlayerMarkdown không được cấu hình, Intlayer sẽ render bằng trình biên dịch mặc định.\n\n Bạn cũng có thể cung cấp các ghi đè cục bộ cho các node cụ thể bằng phương thức `.use()`:\n\n ```typescript\n content().myMarkdownContent.use({\n h1: { class: \"text-3xl font-bold\" },\n })\n ```\n\n Bạn có thể lấy Markdown dưới dạng chuỗi:\n\n ```typescript\n content().myMarkdownContent.value\n String(content().myMarkdownContent)\n content().myMarkdownContent.toString()\n ```\n\n Và bạn có thể truy cập siêu dữ liệu markdown của mình như sau:\n\n ```typescript\n content().myMarkdownContent.metadata\n content().myMarkdownContent.metadata.title\n ```\n\n \n\n\n### 2. Các tiện ích hỗ trợ (Chỉ Chuỗi Markdown)\n\nCác tiện ích này **chỉ render các chuỗi Markdown thô** và độc lập với `useIntlayer`. Hãy sử dụng chúng khi bạn cần render Markdown từ các nguồn khác ngoài từ điển của bạn.\n\n\n \n \n #### Component ``\n\n Render một chuỗi Markdown với các tùy chọn cụ thể.\n\n ```tsx\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n \n {\"# Tiêu đề của tôi\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Nhận một hàm render đã được cấu hình trước.\n\n ```tsx\n import { useMarkdownRenderer } from \"react-intlayer/markdown\";\n\n const renderMarkdown = useMarkdownRenderer({\n forceBlock: true,\n components: { h1: (props) => }\n });\n\n return renderMarkdown(\"# Tiêu đề của tôi\");\n ```\n\n #### Tiện ích `renderMarkdown()`\n Tiện ích độc lập để render bên ngoài các component.\n\n ```tsx\n import { renderMarkdown } from \"react-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Tiêu đề của tôi\", { forceBlock: true });\n ```\n\n \n \n \n #### Component ``\n\n Render một chuỗi Markdown với các tùy chọn cụ thể.\n\n ```tsx\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n \n {\"# Tiêu đề của tôi\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Nhận một hàm render đã được cấu hình trước.\n\n ```tsx\n import { useMarkdownRenderer } from \"next-intlayer/markdown\";\n\n const renderMarkdown = useMarkdownRenderer({\n forceBlock: true,\n components: { h1: (props) => }\n });\n\n return renderMarkdown(\"# Tiêu đề của tôi\");\n ```\n\n #### Tiện ích `renderMarkdown()`\n Tiện ích độc lập để render bên ngoài các component.\n\n ```tsx\n import { renderMarkdown } from \"next-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Tiêu đề của tôi\", { forceBlock: true });\n ```\n\n \n \n\n #### Component ``\n\n ```vue\n \n\n \n \n \n ```\n\n \n \n\n #### Component ``\n\n ```svelte\n \n\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n ```svelte\n \n\n {@html render(\"# Tiêu đề của tôi\")}\n ```\n\n #### Tiện ích `renderMarkdown()`\n\n ```svelte\n \n\n {@html renderMarkdown(\"# Tiêu đề của tôi\")}\n ```\n\n \n \n #### Component ``\n\n ```tsx\n import { MarkdownRenderer } from \"preact-intlayer/markdown\";\n\n \n {\"# Tiêu đề của tôi\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n ```tsx\n import { useMarkdownRenderer } from \"preact-intlayer/markdown\";\n\n const render = useMarkdownRenderer();\n\n return
;\n ```\n\n \n \n #### Service `IntlayerMarkdownService`\n Render một chuỗi Markdown sử dụng service.\n\n ```typescript\n import { IntlayerMarkdownService } from \"angular-intlayer/markdown\";\n\n export class MyComponent {\n constructor(private markdownService: IntlayerMarkdownService) {}\n\n renderMarkdown(markdown: string) {\n return this.markdownService.renderMarkdown(markdown);\n }\n }\n ```\n\n \n\n\n## Cấu hình Toàn cục với `MarkdownProvider`\n\n`MarkdownProvider` (hoặc tương đương trong framework) cấu hình pipeline render Markdown cho toàn bộ ứng dụng của bạn. Điều này áp dụng cho cả render `useIntlayer` tự động và các tiện ích hỗ trợ. Các tùy chọn được đặt ở đây là mặc định — `.use()` sẽ ghi đè chúng ở cấp độ node.\n\n\n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"react-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n ,\n a: ({ href, ...props }) => ,\n MyCustomJSXComponent: (props) => ,\n }}\n >\n {children}\n \n );\n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"react-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n // Use dynamic import to reduce the bundle size of your application\n const { renderMarkdown } = await import('react-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"next-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n ,\n a: ({ href, ...props }) => ,\n MyCustomJSXComponent: (props) => ,\n }}\n >\n {children}\n \n );\n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"next-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n // Use dynamic import to reduce the bundle size of your application\n const { renderMarkdown } = await import('next-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```typescript fileName=\"main.ts\"\n import { createApp } from \"vue\";\n import { intlayer } from \"vue-intlayer\";\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n import App from \"./App.vue\";\n\n const app = createApp(App);\n\n app.use(intlayer);\n app.use(intlayerMarkdown, {\n components: {\n h1: (props) =>\n h('h1', { style: { color: 'orange' }, ...props }, props.children),\n ComponentDemo: () => h('div', { style: { background: 'grey' } }, 'DEMO'),\n bold: (props) => h('strong', props),\n code: (props) => h('code', props),\n },\n });\n\n app.mount(\"#app\");\n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```typescript fileName=\"main.ts\"\n import { createApp } from \"vue\";\n import { intlayer } from \"vue-intlayer\";\n import { intlayerMarkdown } from \"vue-intlayer/markdown\";\n import App from \"./App.vue\";\n\n const app = createApp(App);\n\n app.use(intlayer);\n app.use(intlayerMarkdown, {\n renderMarkdown: async (md) => {\n const { renderMarkdown } = await import('vue-intlayer/markdown');\n return renderMarkdown(md);\n },\n });\n\n app.mount(\"#app\");\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```svelte fileName=\"App.svelte\"\n \n\n \n \n \n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```svelte fileName=\"App.svelte\"\n \n\n {\n const { renderMarkdown } = await import('svelte-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n \n \n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n
{children}
,\n }}\n >\n {children}\n \n );\n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"preact-intlayer/markdown\";\n\n export const AppProvider = ({ children }) => (\n {\n const { renderMarkdown } = await import('preact-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {children}\n \n );\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n export const AppProvider = (props) => (\n
{props.children}
,\n }}\n >\n {props.children}\n \n );\n ```\n\n\n > Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: ``) đều được phân giải dựa trên bản đồ `components`.\n\n Bạn cũng có thể sử dụng trình render markdown của riêng mình:\n\n ```tsx fileName=\"AppProvider.tsx\"\n import { MarkdownProvider } from \"solid-intlayer/markdown\";\n\n export const AppProvider = (props) => (\n {\n const { renderMarkdown } = await import('solid-intlayer/markdown');\n return renderMarkdown(md);\n }}\n >\n {props.children}\n \n );\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n \n\n ```typescript fileName=\"app.module.ts\"\n import { NgModule } from '@angular/core';\n import { IntlayerMarkdownModule } from 'angular-intlayer/markdown';\n\n @NgModule({\n imports: [\n IntlayerMarkdownModule.forRoot({\n renderMarkdown: async (md) => {\n const { renderMarkdown } = await import('angular-intlayer/markdown');\n return renderMarkdown(md);\n }\n })\n ]\n })\n export class AppModule {}\n ```\n\n > Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.\n\n \n\n\n## Suspense\n\nTrình kết xuất Markdown của Intlayer được tải động. Mặc dù được tối ưu hóa, đoạn phân tích cú pháp cơ bản là khoảng 55kb. Tải điều này đồng bộ sẽ trì hoãn kết xuất trang ban đầu và làm suy giảm First Contentful Paint (FCP).\n\nĐể ngăn chặn việc chặn giao diện người dùng, Intlayer tích hợp với Suspense API của React. Nó tìm nạp trình phân tích cú pháp trong nền và ném Promise trong khi tải xuống.\n\nBọc bất kỳ thành phần nào kết xuất Intlayer Markdown trong ranh giới ``. Điều này hiển thị trạng thái dự phòng được bản địa hóa trong khi đoạn phim tải xuống, cho phép phần còn lại của DOM của bạn kết xuất ngay lập tức.\n\nCảnh báo: Nếu bạn không cung cấp ranh giới ``, React sẽ đình chỉ ở cấp gốc hoặc chặn toàn bộ cây thành phần khỏi kết xuất cho đến khi đoạn 55kb được tải hoàn toàn.\n\n\n \n\nTrong Next.js App Router, bạn có thể sử dụng React `Suspense` cho các thành phần máy khách hoặc tệp `loading.tsx` cho các thành phần máy chủ.\n\n**Thành phần máy khách:**\n\n```tsx fileName=\"components/MyComponent.tsx\"\n\"use client\";\nimport { useIntlayer } from \"next-intlayer\";\nimport { Suspense } from \"react\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n**Thành phần máy chủ với `loading.tsx`:**\n\n```tsx fileName=\"app/loading.tsx\"\nexport default function Loading() {\n return
;\n};\n\nexport default MyPage;\n```\n\n \n\n \n\n```tsx\nimport { useIntlayer } from \"react-intlayer\";\nimport { Suspense } from \"react\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n \n\nVue có một thành phần `` được tích hợp sẵn. Bọc thành phần kết xuất nội dung Markdown trong ranh giới ``.\n\n```vue fileName=\"MyComponent.vue\"\n\n\n\n \n \n \n
Loading...
\n \n \n\n```\n\n \n \n\nSvelte không có Suspense API tương đương. Sử dụng khối `{#await}` để xử lý kết xuất không đồng bộ của nội dung Markdown.\n\n```svelte fileName=\"MyComponent.svelte\"\n\n\n{#await $content.markdownContent}\n
Loading...
\n{:then rendered}\n {@html rendered}\n{/await}\n```\n\n \n \n\nPreact hỗ trợ Suspense API của React thông qua `preact/compat`.\n\n```tsx fileName=\"MyComponent.tsx\"\nimport { useIntlayer } from \"preact-intlayer\";\nimport { Suspense } from \"preact/compat\";\n\nconst MyComponent = () => {\n const markdownContent = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n\nSolid có thành phần `` riêng biệt từ `solid-js`.\n\n```tsx fileName=\"MyComponent.tsx\"\nimport { useIntlayer } from \"solid-intlayer\";\nimport { Suspense } from \"solid-js\";\n\nconst MyComponent = () => {\n const { markdownContent } = useIntlayer(\"my-markdown\");\n\n return (\n Loading...}>{markdownContent}\n );\n};\n```\n\n \n \n\nAngular không có Suspense API. Sử dụng chế độ xem có thể trì hoãn (`@defer`) của Angular để xử lý nội dung Markdown được tải chậm (yêu cầu Angular 17+).\n\n```typescript fileName=\"my.component.ts\"\nimport { Component } from \"@angular/core\";\nimport { useIntlayer } from \"angular-intlayer\";\n\n@Component({\n selector: \"app-my\",\n template: `\n @defer {\n \n } @loading {\n
Loading...
\n }\n `,\n})\nexport class MyComponent {\n content = useIntlayer(\"my-markdown\");\n}\n```\n\n \n\n\n---\n\n## Render Phía Server (SSR) và Hydrat Hóa\n\nSo 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.\n\nNhư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.).\n\nThay 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.\n\nBạ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ư ``, `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.\n\n### Ví dụ trong Kiến Trúc Server/Client\n\n\n \n\n ```tsx fileName=\"server.ts\"\n import { parseMarkdown } from \"react-intlayer/markdown\";\n\n // 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa\n export const loader = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Trả về AST dưới dạng JSON cho client\n return Response.json({ content: ast });\n };\n ```\n\n ```tsx fileName=\"client.tsx\"\n import { useLoaderData } from \"react-router\";\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n // 2. 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\n export default function Page() {\n const { content } = useLoaderData();\n\n // Trình kết xuất chấp nhận chuỗi thô hoặc AST đã được phân tích cú pháp\n return ;\n }\n ```\n\n \n \n\n ```tsx fileName=\"app/page.tsx\"\n import { parseMarkdown } from \"next-intlayer/markdown\";\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n export default async function Page() {\n // 1. Phân tích cú pháp markdown thành AST có thể tuần tự hóa trên server\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // 2. Hiển thị trực tiếp AST\n // Trong một Server Component, hoạt động này diễn ra liền mạch và chuyển AST\n // trực tiếp đến các client component bên dưới nếu cần.\n return ;\n }\n ```\n\n \n \n\n ```vue fileName=\"pages/index.vue\"\n \n\n \n \n \n \n ```\n\n \n \n\n ```typescript fileName=\"+page.server.ts\"\n import { parseMarkdown } from \"svelte-intlayer/markdown\";\n\n // 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa\n export const load = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Trả về AST cho client\n return { content: ast };\n };\n ```\n\n ```svelte fileName=\"+page.svelte\"\n \n\n \n \n ```\n\n \n \n\n 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.\n\n ```typescript fileName=\"app.resolver.ts\"\n import { Injectable } from \"@angular/core\";\n import { Resolve } from \"@angular/router\";\n import { parseMarkdown, type ParsedMarkdown } from \"angular-intlayer/markdown\";\n\n @Injectable({ providedIn: \"root\" })\n export class MarkdownResolver implements Resolve {\n resolve(): ParsedMarkdown {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n // 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa\n return parseMarkdown(markdownString);\n }\n }\n ```\n\n ```typescript fileName=\"app.component.ts\"\n import { Component } from \"@angular/core\";\n import { ActivatedRoute } from \"@angular/router\";\n import { IntlayerMarkdownService, type ParsedMarkdown } from \"angular-intlayer/markdown\";\n\n @Component({\n selector: \"app-root\",\n template: ``,\n })\n export class AppComponent {\n renderedMarkdown: string = \"\";\n\n constructor(\n private route: ActivatedRoute,\n private markdownService: IntlayerMarkdownService\n ) {\n // 2. 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\n this.route.data.subscribe((data) => {\n this.renderedMarkdown = this.markdownService.renderMarkdown(\n data.markdownAst\n ) as string;\n });\n }\n }\n ```\n\n \n\n\nMẫ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.\n\n## Tham chiếu tùy chọn\n\nCác tùy chọn này có thể được truyền đến `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` và `renderMarkdown`.\n\n| Option | Type | Default | Mô tả |\n| :-------------------- | :---------- | :------ | :------------------------------------------------------------------------------------ |\n| `forceBlock` | `boolean` | `false` | Bắt buộc đầu ra phải được bọc trong một phần tử cấp khối (ví dụ: `
`). |\n| `forceInline` | `boolean` | `false` | Bắt buộc đầu ra phải được bọc trong một phần tử nội tuyến (ví dụ: ``). |\n| `tagfilter` | `boolean` | `true` | Bật Bộ lọc thẻ GitHub để cải thiện bảo mật bằng cách loại bỏ các thẻ HTML nguy hiểm. |\n| `preserveFrontmatter` | `boolean` | `false` | Nếu `true`, frontmatter ở đầu chuỗi Markdown sẽ không bị tước đi. |\n| `components` | `Overrides` | `{}` | Bản đồ các thẻ HTML cho các thành phần tùy chỉnh (ví dụ: `{ h1: MyHeading }`). |\n| `wrapper` | `Component` | `null` | Thành phần tùy chỉnh để bọc Markdown đã kết xuất. |\n| `renderMarkdown` | `Function` | `null` | Chức năng kết xuất tùy chỉnh để thay thế hoàn toàn trình biên dịch Markdown mặc định. |\n","description":"Tìm hiểu cách khai báo và sử dụng nội dung Markdown trong trang web đa ngôn ngữ của bạn với Intlayer. Làm theo các bước trong tài liệu trực tuyến này để tích hợp Markdown một cách liền mạch vào dự án của bạn.","url":"https://intlayer.org/vi/doc/concept/content/markdown","datePublished":"2025-02-07","dateModified":"2026-05-19","version":"8.11.0","keywords":"Markdown, Quốc tế hóa, Tài liệu, Intlayer, Next.js, JavaScript, React","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Nhà phát triển (Developers), Quản trị nội dung (Content Managers)"}}
Intlayer hỗ trợ nội dung rich text được định nghĩa bằng cú pháp Markdown. Điều này cho phép bạn dễ dàng viết và duy trì nội dung được định dạng phong phú như blog, bài viết, và hơn thế nữa.
Khai báo Nội dung Markdown
Bạn có thể khai báo nội dung Markdown bằng cách sử dụng hàm md hoặc đơn giản là một chuỗi (nếu nó chứa cú pháp Markdown).
Bắt đầu từ phiên bản 8.10.0, bạn có thể khai báo nội dung Markdown trực tiếp trong các tệp .content.md. Intlayer sẽ tự động phát hiện và phân tích nội dung Markdown.
markdown-file.en.content.md
Sao chép mã
Sao chép mã vào clipboard
---key: my-markdown-contentdescription: Nội dung của tôilocale: en---# Nội dung của tôiDưới đây là một ví dụ về nội dung markdown
Trường front-matter locale là trường xác định ngôn ngữ của nội dung. Nó là tùy chọn. Nếu không được cung cấp, Intlayer sẽ sử dụng ngôn ngữ mặc định, ngôn ngữ này cũng được sử dụng làm ngôn ngữ dự phòng nếu không có bản dịch cho một ngôn ngữ cụ thể.
Bạn có thể thêm vào front-matter bất kỳ thuộc tính nào được định nghĩa trong Định nghĩa Từ điển
Sử dụng hàm md để khai báo rõ ràng nội dung Markdown. Điều này rất hữu ích nếu bạn muốn đảm bảo một chuỗi được xử lý như Markdown ngay cả khi nó không chứa cú pháp rõ ràng.
markdownDictionary.content.ts
Sao chép mã
Sao chép mã vào clipboard
import { md, type Dictionary } from "intlayer";const markdownDictionary = { key: "app", content: { myMarkdownContent: md("## Tiêu đề của tôi \n\nLorem Ipsum"), },} satisfies Dictionary;export default markdownDictionary;
Nhập trực tiếp các tệp .md bằng cách sử dụng hàm file.
Nếu chuỗi chứa các chỉ báo Markdown phổ biến (như tiêu đề, danh sách, liên kết, v.v.), Intlayer sẽ tự động chuyển đổi nó.
markdownDictionary.content.ts
Sao chép mã
Sao chép mã vào clipboard
export default { key: "app", contentAutoTransformation: true, // Bật phát hiện tự động nội dung Markdown - Có thể được đặt toàn cục trong intlayer.config.ts content: { myMarkdownContent: "## Tiêu đề của tôi \n\nLorem Ipsum", },};
Render Markdown
Intlayer cung cấp hai cách độc lập để render Markdown:
Thông qua useIntlayer
— Intlayer tự động chuyển đổi node md thành đầu ra nguyên bản của framework (JSX, VNode, chuỗi HTML).
Frontmatter được phân tích cú pháp và hiển thị dưới dạng .metadata. Bạn có thể ghi đè quá trình render ở hai cấp độ — toàn cục với MarkdownProvider (hoặc tương đương trong framework) và cục bộ trên mỗi node bằng .use(). Cả hai đều có thể được kết hợp; .use() được ưu tiên hơn MarkdownProvider, và MarkdownProvider được ưu tiên hơn mặc định.
Các tiện ích hỗ trợ — <MarkdownRenderer />, useMarkdownRenderer(), và renderMarkdown() là các công cụ độc lập chấp nhận chỉ các chuỗi Markdown thô. Chúng độc lập với useIntlayer và không hoạt động với các node được trang trí mà nó trả về.
Render Markdown hỗ trợ MDX — sử dụng bất kỳ component JSX/framework nào bằng tên trực tiếp bên trong Markdown của bạn.
1. Render Tự động (thông qua useIntlayer)
Các node Markdown có thể được render trực tiếp dưới dạng JSX.
Các tiện ích này chỉ render các chuỗi Markdown thô và độc lập với useIntlayer. Hãy sử dụng chúng khi bạn cần render Markdown từ các nguồn khác ngoài từ điển của bạn.
Component <MarkdownRenderer />
Render một chuỗi Markdown với các tùy chọn cụ thể.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer forceBlock={true} tagfilter={true}> {"# Tiêu đề của tôi"}</MarkdownRenderer>
Hook useMarkdownRenderer()
Nhận một hàm render đã được cấu hình trước.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { useMarkdownRenderer } from "react-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({ forceBlock: true, components: { h1: (props) => <h1 {...props} className="custom" /> }});return renderMarkdown("# Tiêu đề của tôi");
Tiện ích renderMarkdown()
Tiện ích độc lập để render bên ngoài các component.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { renderMarkdown } from "react-intlayer/markdown";const jsx = renderMarkdown("# Tiêu đề của tôi", { forceBlock: true });
Component <MarkdownRenderer />
Render một chuỗi Markdown với các tùy chọn cụ thể.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownRenderer } from "next-intlayer/markdown";<MarkdownRenderer forceBlock={true} tagfilter={true}> {"# Tiêu đề của tôi"}</MarkdownRenderer>
Hook useMarkdownRenderer()
Nhận một hàm render đã được cấu hình trước.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { useMarkdownRenderer } from "next-intlayer/markdown";const renderMarkdown = useMarkdownRenderer({ forceBlock: true, components: { h1: (props) => <h1 {...props} className="custom" /> }});return renderMarkdown("# Tiêu đề của tôi");
Tiện ích renderMarkdown()
Tiện ích độc lập để render bên ngoài các component.
tsx
Sao chép mã
Sao chép mã vào clipboard
import { renderMarkdown } from "next-intlayer/markdown";const jsx = renderMarkdown("# Tiêu đề của tôi", { forceBlock: true });
Component <MarkdownRenderer />
vue
Sao chép mã
Sao chép mã vào clipboard
<script setup>import { MarkdownRenderer } from "vue-intlayer/markdown";</script><template> <MarkdownRenderer :forceBlock="true" content="# Tiêu đề của tôi" /></template>
Component <MarkdownRenderer />
svelte
Sao chép mã
Sao chép mã vào clipboard
<script lang="ts">import { MarkdownRenderer } from "svelte-intlayer/markdown";</script><MarkdownRenderer forceBlock={true} value="# Tiêu đề của tôi" />
Hook useMarkdownRenderer()
svelte
Sao chép mã
Sao chép mã vào clipboard
<script lang="ts">import { useMarkdownRenderer } from "svelte-intlayer/markdown";const render = useMarkdownRenderer();</script>{@html render("# Tiêu đề của tôi")}
Tiện ích renderMarkdown()
svelte
Sao chép mã
Sao chép mã vào clipboard
<script lang="ts">import { renderMarkdown } from "svelte-intlayer/markdown";</script>{@html renderMarkdown("# Tiêu đề của tôi")}
Component <MarkdownRenderer />
tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownRenderer } from "preact-intlayer/markdown";<MarkdownRenderer forceBlock={true}> {"# Tiêu đề của tôi"}</MarkdownRenderer>
Hook useMarkdownRenderer()
tsx
Sao chép mã
Sao chép mã vào clipboard
import { useMarkdownRenderer } from "preact-intlayer/markdown";const render = useMarkdownRenderer();return <div>{render("# Tiêu đề của tôi")}</div>;
Tiện ích renderMarkdown()
tsx
Sao chép mã
Sao chép mã vào clipboard
import { renderMarkdown } from "preact-intlayer/markdown";return <div>{renderMarkdown("# Tiêu đề của tôi")}</div>;
Component <MarkdownRenderer />
tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownRenderer } from "solid-intlayer/markdown";<MarkdownRenderer forceBlock={true}> {"# Tiêu đề của tôi"}</MarkdownRenderer>
Hook useMarkdownRenderer()
tsx
Sao chép mã
Sao chép mã vào clipboard
import { useMarkdownRenderer } from "solid-intlayer/markdown";const render = useMarkdownRenderer();return <div>{render("# Tiêu đề của tôi")}</div>;
Tiện ích renderMarkdown()
tsx
Sao chép mã
Sao chép mã vào clipboard
import { renderMarkdown } from "solid-intlayer/markdown";return <div>{renderMarkdown("# Tiêu đề của tôi")}</div>;
Service IntlayerMarkdownService
Render một chuỗi Markdown sử dụng service.
typescript
Sao chép mã
Sao chép mã vào clipboard
import { IntlayerMarkdownService } from "angular-intlayer/markdown";export class MyComponent { constructor(private markdownService: IntlayerMarkdownService) {} renderMarkdown(markdown: string) { return this.markdownService.renderMarkdown(markdown); }}
Cấu hình Toàn cục với MarkdownProvider
MarkdownProvider (hoặc tương đương trong framework) cấu hình pipeline render Markdown cho toàn bộ ứng dụng của bạn. Điều này áp dụng cho cả render useIntlayer tự động và các tiện ích hỗ trợ. Các tùy chọn được đặt ở đây là mặc định — .use() sẽ ghi đè chúng ở cấp độ node.
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
AppProvider.tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownProvider } from "react-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider renderMarkdown={async (md) => { // Use dynamic import to reduce the bundle size of your application const { renderMarkdown } = await import('react-intlayer/markdown'); return renderMarkdown(md); }} > {children} </MarkdownProvider>);
Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
AppProvider.tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownProvider } from "next-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider renderMarkdown={async (md) => { // Use dynamic import to reduce the bundle size of your application const { renderMarkdown } = await import('next-intlayer/markdown'); return renderMarkdown(md); }} > {children} </MarkdownProvider>);
Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
main.ts
Sao chép mã
Sao chép mã vào clipboard
import { createApp } from "vue";import { intlayer } from "vue-intlayer";import { intlayerMarkdown } from "vue-intlayer/markdown";import App from "./App.vue";const app = createApp(App);app.use(intlayer);app.use(intlayerMarkdown, { renderMarkdown: async (md) => { const { renderMarkdown } = await import('vue-intlayer/markdown'); return renderMarkdown(md); },});app.mount("#app");
Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.
App.svelte
Sao chép mã
Sao chép mã vào clipboard
<script lang="ts"> import { MarkdownProvider } from "svelte-intlayer/markdown"; import MyHeading from "./MyHeading.svelte";</script><MarkdownProvider components={{ h1: MyHeading, }}> <slot /></MarkdownProvider>
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.
AppProvider.tsx
Sao chép mã
Sao chép mã vào clipboard
import { MarkdownProvider } from "preact-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider components={{ h1: ({ children }) => <h1 className="text-2xl font-bold">{children}</h1>, }} > {children} </MarkdownProvider>);
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
Hỗ trợ MDX — bất kỳ tên component nào được sử dụng bên trong Markdown của bạn (ví dụ: <MyCustomJSXComponent />) đều được phân giải dựa trên bản đồ components.
Bạn cũng có thể sử dụng trình render markdown của riêng mình:
Việc nhập trình render Markdown của bạn một cách động là một cách tuyệt vời để giảm dung lượng bundle của ứng dụng.
Suspense
Trình kết xuất Markdown của Intlayer được tải động. Mặc dù được tối ưu hóa, đoạn phân tích cú pháp cơ bản là khoảng 55kb. Tải điều này đồng bộ sẽ trì hoãn kết xuất trang ban đầu và làm suy giảm First Contentful Paint (FCP).
Để ngăn chặn việc chặn giao diện người dùng, Intlayer tích hợp với Suspense API của React. Nó tìm nạp trình phân tích cú pháp trong nền và ném Promise trong khi tải xuống.
Bọc bất kỳ thành phần nào kết xuất Intlayer Markdown trong ranh giới <Suspense>. Điều này hiển thị trạng thái dự phòng được bản địa hóa trong khi đoạn phim tải xuống, cho phép phần còn lại của DOM của bạn kết xuất ngay lập tức.
Cảnh báo: Nếu bạn không cung cấp ranh giới <Suspense>, React sẽ đình chỉ ở cấp gốc hoặc chặn toàn bộ cây thành phần khỏi kết xuất cho đến khi đoạn 55kb được tải hoàn toàn.
Trong Next.js App Router, bạn có thể sử dụng React Suspense cho các thành phần máy khách hoặc tệp loading.tsx cho các thành phần máy chủ.
Angular không có Suspense API. Sử dụng chế độ xem có thể trì hoãn (@defer) của Angular để xử lý nội dung Markdown được tải chậm (yêu cầu Angular 17+).
my.component.ts
Sao chép mã
Sao chép mã vào clipboard
import { Component } from "@angular/core";import { useIntlayer } from "angular-intlayer";@Component({selector: "app-my",template: ` @defer { <div [innerHTML]="content().markdownContent"></div> } @loading { <div>Loading...</div> }`,})export class MyComponent {content = useIntlayer("my-markdown");}
Render Phía Server (SSR) và Hydrat Hóa
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.
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.).
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.
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.
Ví dụ trong Kiến Trúc Server/Client
server.ts
Sao chép mã
Sao chép mã vào clipboard
import { parseMarkdown } from "react-intlayer/markdown";// 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóaexport const loader = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Trả về AST dưới dạng JSON cho client return Response.json({ content: ast });};
client.tsx
Sao chép mã
Sao chép mã vào clipboard
import { useLoaderData } from "react-router";import { MarkdownRenderer } from "react-intlayer/markdown";// 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ạiexport default function Page() { const { content } = useLoaderData(); // Trình kết xuất chấp nhận chuỗi thô hoặc AST đã được phân tích cú pháp return <MarkdownRenderer content={content} />;}
app/page.tsx
Sao chép mã
Sao chép mã vào clipboard
import { parseMarkdown } from "next-intlayer/markdown";import { MarkdownRenderer } from "next-intlayer/markdown";export default async function Page() { // 1. Phân tích cú pháp markdown thành AST có thể tuần tự hóa trên server const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // 2. Hiển thị trực tiếp AST // Trong một Server Component, hoạt động này diễn ra liền mạch và chuyển AST// trực tiếp đến các client component bên dưới nếu cần. return <MarkdownRenderer content={ast} />;}
pages/index.vue
Sao chép mã
Sao chép mã vào clipboard
<script setup lang="ts">import { parseMarkdown } from "vue-intlayer/markdown";import { MarkdownRenderer } from "vue-intlayer/markdown";// 1. Lấy và phân tích cú pháp markdown thành AST trên serverconst { data: ast } = await useAsyncData('markdown', () => { const markdownString = "## My title \n\nLorem Ipsum"; return parseMarkdown(markdownString);});</script><template> <!-- 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 --> <MarkdownRenderer :content="ast" /></template>
+page.server.ts
Sao chép mã
Sao chép mã vào clipboard
import { parseMarkdown } from "svelte-intlayer/markdown";// 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóaexport const load = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Trả về AST cho client return { content: ast };};
+page.svelte
Sao chép mã
Sao chép mã vào clipboard
<script lang="ts"> import { MarkdownRenderer } from "svelte-intlayer/markdown"; export let data;</script><!-- 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 --><MarkdownRenderer value={data.content} />
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.
app.resolver.ts
Sao chép mã
Sao chép mã vào clipboard
import { Injectable } from "@angular/core";import { Resolve } from "@angular/router";import { parseMarkdown, type ParsedMarkdown } from "angular-intlayer/markdown";@Injectable({ providedIn: "root" })export class MarkdownResolver implements Resolve<ParsedMarkdown> { resolve(): ParsedMarkdown { const markdownString = "## My title \n\nLorem Ipsum"; // 1. Trên server: Phân tích cú pháp markdown thành AST có thể tuần tự hóa return parseMarkdown(markdownString); }}
app.component.ts
Sao chép mã
Sao chép mã vào clipboard
import { Component } from "@angular/core";import { ActivatedRoute } from "@angular/router";import { IntlayerMarkdownService, type ParsedMarkdown } from "angular-intlayer/markdown";@Component({ selector: "app-root", template: `<div [innerHTML]="renderedMarkdown"></div>`,})export class AppComponent { renderedMarkdown: string = ""; constructor( private route: ActivatedRoute, private markdownService: IntlayerMarkdownService ) { // 2. 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 this.route.data.subscribe((data) => { this.renderedMarkdown = this.markdownService.renderMarkdown( data.markdownAst ) as string; }); }}
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.
Tham chiếu tùy chọn
Các tùy chọn này có thể được truyền đến MarkdownProvider, MarkdownRenderer, useMarkdownRenderer và renderMarkdown.
Hiển thị tất cả nội dung bảng
Mở bảng trong một cửa sổ bật lên để xem toàn bộ nội dung dữ liệu một cách rõ ràng
Option
Type
Default
Mô tả
forceBlock
boolean
false
Bắt buộc đầu ra phải được bọc trong một phần tử cấp khối (ví dụ: <div>).
forceInline
boolean
false
Bắt buộc đầu ra phải được bọc trong một phần tử nội tuyến (ví dụ: <span>).
tagfilter
boolean
true
Bật Bộ lọc thẻ GitHub để cải thiện bảo mật bằng cách loại bỏ các thẻ HTML nguy hiểm.
preserveFrontmatter
boolean
false
Nếu true, frontmatter ở đầu chuỗi Markdown sẽ không bị tước đi.
components
Overrides
{}
Bản đồ các thẻ HTML cho các thành phần tùy chỉnh (ví dụ: { h1: MyHeading }).
wrapper
Component
null
Thành phần tùy chỉnh để bọc Markdown đã kết xuất.
renderMarkdown
Function
null
Chức năng kết xuất tùy chỉnh để thay thế hoàn toàn trình biên dịch Markdown mặc định.