\n\n \n \n \n ```\n\n Глобальне налаштування через плагін `intlayerMarkdown` (підтримує власні компоненти 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), // MDX-компонент\n },\n });\n ```\n\n > Якщо плагін `intlayerMarkdown` не встановлено, Intlayer рендеритиме за допомогою компілятора за замовчуванням.\n\n Ви також можете надати локальні перевизначення для конкретних вузлів за допомогою методу `.use()`:\n\n ```vue\n h('h1', { style: { color: 'red' } }, props.children),\n })\" />\n ```\n\n Ви можете отримати Markdown як рядок:\n\n ```vue\n {{ myMarkdownContent.value }}\n {{ String(myMarkdownContent) }}\n {{ myMarkdownContent.toString() }}\n ```\n\n І ви можете отримати доступ до метаданих markdown наступним чином:\n\n ```vue\n \n \n ```\n\n \n \n Svelte за замовчуванням рендерить Markdown як HTML-рядок. Використовуйте `{@html}`, щоб його відрендерити.\n\n ```svelte fileName=\"App.svelte\"\n \n\n \n {@html $content.myMarkdownContent}\n \n ```\n\n > Якщо `MarkdownProvider` відсутній, Intlayer рендеритиме markdown за допомогою компілятора за замовчуванням.\n\n Ви також можете надати локальні перевизначення для конкретних вузлів за допомогою методу `.use()`:\n\n ```svelte\n {@html $content.myMarkdownContent.use({ ... })}\n ```\n\n Ви можете отримати Markdown як рядок:\n\n ```svelte\n {$content.myMarkdownContent.value}\n {String($content.myMarkdownContent)}\n {$content.myMarkdownContent.toString()}\n ```\n\n І ви можете отримати доступ до метаданих markdown наступним чином:\n\n ```svelte\n {$content.myMarkdownContent.metadata}\n {$content.myMarkdownContent.metadata.title}\n ```\n\n \n \n Preact підтримує вузли Markdown безпосередньо у 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) => , // MDX-компонент\n }}\n >\n \n \n );\n ```\n\n > Якщо `MarkdownProvider` відсутній, Intlayer рендеритиме markdown, використовуючи стандартний парсер Markdown у JSX.\n\n Ви також можете надати локальні перевизначення для конкретних вузлів за допомогою методу `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: ({ children }) =>
{children}
,\n })}\n ```\n\n Ви можете отримати Markdown як рядок:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n І ви можете отримати доступ до метаданих markdown наступним чином:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Solid підтримує вузли Markdown безпосередньо у 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) => , // MDX-компонент\n }}\n >\n \n \n );\n ```\n\n > Якщо `MarkdownProvider` відсутній, Intlayer рендеритиме markdown, використовуючи стандартний парсер Markdown у JSX.\n\n Ви також можете надати локальні перевизначення для конкретних вузлів за допомогою методу `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: (props) =>
{props.children}
,\n })}\n ```\n\n Ви можете отримати Markdown як рядок:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n І ви можете отримати доступ до метаданих markdown наступним чином:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Angular використовує директиву `[innerHTML]` для рендерингу вмісту 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 > Якщо провайдер IntlayerMarkdown не налаштовано, Intlayer рендеритиме за допомогою компілятора за замовчуванням.\n\n Ви також можете надати локальні перевизначення для конкретних вузлів за допомогою методу `.use()`:\n\n ```typescript\n content().myMarkdownContent.use({\n h1: { class: \"text-3xl font-bold\" },\n })\n ```\n\n Ви можете отримати Markdown як рядок:\n\n ```typescript\n content().myMarkdownContent.value\n String(content().myMarkdownContent)\n content().myMarkdownContent.toString()\n ```\n\n І ви можете отримати доступ до метаданих markdown наступним чином:\n\n ```typescript\n content().myMarkdownContent.metadata\n content().myMarkdownContent.metadata.title\n ```\n\n \n\n\n### 2. Допоміжні утиліти (тільки рядки Markdown)\n\nЦі утиліти рендерять **тільки необроблені рядки Markdown** і не залежать від `useIntlayer`. Використовуйте їх, коли вам потрібно відрендерити Markdown з джерел, відмінних від ваших словників.\n\n\n \n \n #### Компонент ``\n\n Рендерить рядок Markdown з певними опціями.\n\n ```tsx\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n \n {\"# Мій Заголовок\"}\n \n ```\n\n #### Хук `useMarkdownRenderer()`\n\n Отримайте попередньо налаштовану функцію рендерингу.\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(\"# Мій Заголовок\");\n ```\n\n #### Утиліта `renderMarkdown()`\n Окрема утиліта для рендерингу поза компонентами.\n\n ```tsx\n import { renderMarkdown } from \"react-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Мій Заголовок\", { forceBlock: true });\n ```\n\n \n \n \n #### Компонент ``\n\n Рендерить рядок Markdown з певними опціями.\n\n ```tsx\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n \n {\"# Мій Заголовок\"}\n \n ```\n\n #### Хук `useMarkdownRenderer()`\n\n Отримайте попередньо налаштовану функцію рендерингу.\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(\"# Мій Заголовок\");\n ```\n\n #### Утиліта `renderMarkdown()`\n Окрема утиліта для рендерингу поза компонентами.\n\n ```tsx\n import { renderMarkdown } from \"next-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Мій Заголовок\", { forceBlock: true });\n ```\n\n \n \n\n #### Компонент ``\n\n ```vue\n \n\n \n \n \n ```\n\n \n \n\n #### Компонент ``\n\n ```svelte\n \n\n \n ```\n\n #### Хук `useMarkdownRenderer()`\n\n ```svelte\n \n\n {@html render(\"# Мій Заголовок\")}\n ```\n\n #### Утиліта `renderMarkdown()`\n\n ```svelte\n \n\n {@html renderMarkdown(\"# Мій Заголовок\")}\n ```\n\n \n \n #### Компонент ``\n\n ```tsx\n import { MarkdownRenderer } from \"preact-intlayer/markdown\";\n\n \n {\"# Мій Заголовок\"}\n \n ```\n\n #### Хук `useMarkdownRenderer()`\n\n ```tsx\n import { useMarkdownRenderer } from \"preact-intlayer/markdown\";\n\n const render = useMarkdownRenderer();\n\n return
;\n ```\n\n \n \n #### Сервіс `IntlayerMarkdownService`\n Рендерить рядок Markdown за допомогою сервісу.\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## Глобальне налаштування за допомогою `MarkdownProvider`\n\n`MarkdownProvider` (або його еквівалент у фреймворку) налаштовує конвеєр рендерингу Markdown для всього вашого додатку. Це стосується як автоматичного рендерингу `useIntlayer`, так і допоміжних утиліт. Налаштування, вказані тут, є значеннями за замовчуванням — `.use()` перевизначає їх на рівні вузла.\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 > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\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 > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\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 > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\n\n \n \n\n ```svelte fileName=\"App.svelte\"\n \n\n \n \n \n ```\n\n\n > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\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 > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\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 > Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, ``), розпізнається відповідно до карти `components`.\n\n Ви також можете використовувати власний рендерер markdown:\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\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 > Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.\n\n \n\n\n## Suspense\n\nРендерер Markdown Intlayer завантажується динамічно. Хоча він оптимізований, базовий фрагмент аналізатора становить близько 55 кБ. Синхронне завантаження цього затримує початковий рендеринг сторінки та погіршує First Contentful Paint (FCP).\n\nЩоб запобігти блокуванню інтерфейсу користувача, Intlayer інтегрується з API Suspense від React. Він завантажує аналізатор у фоновому режимі та створює Promise під час завантаження.\n\nОберніть будь-який компонент, що відображає Intlayer Markdown, у межу ``. Це показує локалізований резервний стан під час завантаження фрагмента, дозволяючи решті вашого DOM відображатися негайно.\n\nПопередження: Якщо ви не надасте межу ``, React призупинить рендеринг на кореневому рівні або заблокує рендеринг всього дерева компонентів, доки фрагмент у 55 кБ не буде повністю завантажений.\n\n\n \n\nУ маршрутизаторі Next.js App Router ви можете використовувати або React `Suspense` для клієнтських компонентів, або файл `loading.tsx` для серверних компонентів.\n\n**Клієнтський компонент:**\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**Серверний компонент з `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 має вбудований компонент ``. Оберніть компонент, який відображає вміст Markdown, у межу ``.\n\n```vue fileName=\"MyComponent.vue\"\n\n\n\n \n \n \n
Loading...
\n \n \n\n```\n\n \n \n\nSvelte не має еквівалента API Suspense. Використовуйте блок `{#await}` для обробки асинхронного рендерингу вмісту 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 підтримує API React Suspense через `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 має власний компонент `` від `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 не має API Suspense. Використовуйте відкладені представлення (`@defer`) в Angular для обробки вмісту Markdown із відкладеним завантаженням (потрібен 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## Рендеринг на стороні сервера (SSR) та гідратація\n\nУ порівнянні з іншими парсерами Markdown, такими як remark / rehype, Intlayer Markdown не має залежностей і працює як на клієнті, так і на сервері.\n\nОднак Intlayer оптимізує синтаксичний аналіз для фреймворків серверного рендерингу (SSR) (таких як Next.js App Router, React Router, Nuxt, SvelteKit тощо).\n\nЗамість надсилання необроблених рядків Markdown клієнту та їх аналізу в браузері (що призводить до зниження продуктивності), Intlayer дозволяє попередньо проаналізувати Markdown в абстрактне синтаксичне дерево (AST) на сервері.\n\nВи можете використовувати функцію `parseMarkdown` з пакету Intlayer вашого фреймворку на стороні сервера для генерації серіалізованого AST (об'єкта `ParsedMarkdown`) і передачі його безпосередньо на фронтенд. Всі утиліти рендерингу Intlayer (такі як ``, `useMarkdownRenderer` тощо) автоматично приймають цей об'єкт AST і плавно рендерять його.\n\n### Приклад в архітектурі Сервер/Клієнт\n\n\n \n\n ```tsx fileName=\"server.ts\"\n import { parseMarkdown } from \"react-intlayer/markdown\";\n\n // 1. На сервері: перетворити markdown на серіалізоване AST\n export const loader = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Повернути AST клієнту у форматі JSON\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. На клієнті: відрендерити AST безпосередньо без повторного аналізу\n export default function Page() {\n const { content } = useLoaderData();\n\n // Рендерер приймає або необроблений рядок, або проаналізоване AST\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. Перетворити markdown на серіалізоване AST на сервері\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // 2. Відрендерити AST безпосередньо\n // У серверному компоненті це працює безшовно і передає AST\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. На сервері: перетворити markdown на серіалізоване AST\n export const load = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Повернути AST клієнту\n return { content: ast };\n };\n ```\n\n ```svelte fileName=\"+page.svelte\"\n \n\n \n \n ```\n\n \n \n\n Angular SSR зазвичай отримує дані на сервері під час початкового завантаження та виконує гідратацію на клієнті. Ви можете використовувати резолвери для передачі 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. На сервері: перетворити markdown на серіалізоване AST\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. На клієнті: відрендерити AST безпосередньо без повторного аналізу\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\nЦей підхід гарантує, що логіка аналізу Markdown повністю виконується на сервері, що значно скорочує час виконання на стороні клієнта та підвищує швидкість початкової гідратації.\n\n## Довідник опцій\n\nЦі параметри можна передати до `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` та `renderMarkdown`.\n\n| Option | Type | Default | Опис |\n| :-------------------- | :---------- | :------ | :------------------------------------------------------------------------------------------- |\n| `forceBlock` | `boolean` | `false` | Примушує вивід обгортатися блочним елементом (наприклад, `
`). |\n| `forceInline` | `boolean` | `false` | Примушує вивід обгортатися вбудованим елементом (наприклад, ``). |\n| `tagfilter` | `boolean` | `true` | Увімкнює фільтр тегів GitHub для підвищення безпеки шляхом видалення небезпечних тегів HTML. |\n| `preserveFrontmatter` | `boolean` | `false` | Якщо `true`, початкові метадані (frontmatter) на початку рядка Markdown не будуть видалені. |\n| `components` | `Overrides` | `{}` | Карта тегів HTML до власних компонентів (наприклад, `{ h1: MyHeading }`). |\n| `wrapper` | `Component` | `null` | Спеціальний компонент для обгортання відображеного Markdown. |\n| `renderMarkdown` | `Function` | `null` | Власна функція рендерингу для повної заміни компілятора Markdown за замовчуванням. |\n","description":"Дізнайтеся, як оголошувати та використовувати вміст Markdown на вашому багатомовному веб-сайті за допомогою Intlayer. Дотримуйтесь інструкцій у цій онлайн-документації, щоб безперешкодно інтегрувати Markdown у ваш проект.","url":"https://intlayer.org/uk/doc/concept/content/markdown","datePublished":"2025-02-07","dateModified":"2026-05-19","version":"8.11.0","keywords":"Markdown, Інтернаціоналізація, Документація, Intlayer, Next.js, JavaScript, React","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Розробники, менеджери контенту"}}
Скопіювати документацію у форматі Markdown в буфер обміну
Markdown / Вміст форматованого тексту
Intlayer підтримує вміст форматованого тексту, визначений за допомогою синтаксису Markdown. Це дозволяє легко створювати та підтримувати форматований вміст, такий як блоги, статті тощо.
Оголошення вмісту Markdown
Ви можете оголосити вміст Markdown за допомогою функції md або просто як рядок (якщо він містить синтаксис Markdown).
Починаючи з версії 8.10.0, ви можете оголошувати вміст Markdown безпосередньо у файлах .content.md. Intlayer автоматично виявлятиме та аналізуватиме вміст Markdown.
markdown-file.en.content.md
Копіювати код
Скопіюйте код у буфер обміну
---key: my-markdown-contentdescription: Мій вмістlocale: en---# Мій вмістОсь приклад вмісту markdown
Поле front-matter locale визначає локаль вмісту. Воно є необов'язковим. Якщо його не вказано, Intlayer використовуватиме локаль за замовчуванням, яка також слугуватиме резервною, якщо переклад для конкретної локалі недоступний.
У front-matter ви можете додати будь-які властивості, визначені у Визначенні словника
Використовуйте функцію md для явного оголошення вмісту Markdown. Це корисно, якщо ви хочете переконатися, що рядок обробляється як Markdown, навіть якщо він не містить очевидного синтаксису.
Якщо рядок містить типові індикатори Markdown (наприклад, заголовки, списки, посилання тощо), Intlayer автоматично перетворить його.
markdownDictionary.content.ts
Копіювати код
Скопіюйте код у буфер обміну
export default { key: "app", contentAutoTransformation: true, // Увімкнути автоматичне виявлення вмісту Markdown - Можна налаштувати глобально в intlayer.config.ts content: { myMarkdownContent: "## Мій заголовок \n\nLorem Ipsum", },};
Рендеринг Markdown
Intlayer надає два незалежні способи рендерингу Markdown:
Через useIntlayer
— Intlayer автоматично перетворює вузол md у нативний вихідний формат фреймворку (JSX, VNode, HTML-рядок).
Frontmatter аналізується та надається як .metadata. Ви можете перевизначити рендеринг на двох рівнях — глобально за допомогою MarkdownProvider (або еквівалента фреймворку) та локально для кожного вузла за допомогою .use(). Обидва підходи можна комбінувати; .use() має пріоритет над MarkdownProvider, який має пріоритет над поведінкою за замовчуванням.
Допоміжні утиліти — <MarkdownRenderer />, useMarkdownRenderer() та renderMarkdown() є самостійними інструментами, які приймають тільки необроблені рядки Markdown. Вони не залежать від useIntlayer і не працюють з оформленими вузлами, які він повертає.
Рендеринг Markdown підтримує MDX — використовуйте будь-який компонент JSX/фреймворку за назвою безпосередньо у вашому Markdown.
1. Автоматичний рендеринг (через useIntlayer)
Вузли Markdown можна рендерити безпосередньо як JSX.
Ці утиліти рендерять тільки необроблені рядки Markdown і не залежать від useIntlayer. Використовуйте їх, коли вам потрібно відрендерити Markdown з джерел, відмінних від ваших словників.
import { renderMarkdown } from "solid-intlayer/markdown";return <div>{renderMarkdown("# Мій Заголовок")}</div>;
Сервіс IntlayerMarkdownService
Рендерить рядок Markdown за допомогою сервісу.
typescript
Копіювати код
Скопіюйте код у буфер обміну
import { IntlayerMarkdownService } from "angular-intlayer/markdown";export class MyComponent { constructor(private markdownService: IntlayerMarkdownService) {} renderMarkdown(markdown: string) { return this.markdownService.renderMarkdown(markdown); }}
Глобальне налаштування за допомогою MarkdownProvider
MarkdownProvider (або його еквівалент у фреймворку) налаштовує конвеєр рендерингу Markdown для всього вашого додатку. Це стосується як автоматичного рендерингу useIntlayer, так і допоміжних утиліт. Налаштування, вказані тут, є значеннями за замовчуванням — .use() перевизначає їх на рівні вузла.
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
AppProvider.tsx
Копіювати код
Скопіюйте код у буфер обміну
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>);
Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
AppProvider.tsx
Копіювати код
Скопіюйте код у буфер обміну
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>);
Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
main.ts
Копіювати код
Скопіюйте код у буфер обміну
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");
Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.
App.svelte
Копіювати код
Скопіюйте код у буфер обміну
<script lang="ts"> import { MarkdownProvider } from "svelte-intlayer/markdown"; import MyHeading from "./MyHeading.svelte";</script><MarkdownProvider components={{ h1: MyHeading, }}> <slot /></MarkdownProvider>
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.
AppProvider.tsx
Копіювати код
Скопіюйте код у буфер обміну
import { MarkdownProvider } from "preact-intlayer/markdown";export const AppProvider = ({ children }) => ( <MarkdownProvider components={{ h1: ({ children }) => <h1 className="text-2xl font-bold">{children}</h1>, }} > {children} </MarkdownProvider>);
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
Підтримується MDX — будь-яка назва компонента, яка використовується всередині вашого Markdown (наприклад, <MyCustomJSXComponent />), розпізнається відповідно до карти components.
Ви також можете використовувати власний рендерер markdown:
Динамічний імпорт вашого рендерера Markdown — чудовий спосіб зменшити розмір бандлу вашого додатка.
Suspense
Рендерер Markdown Intlayer завантажується динамічно. Хоча він оптимізований, базовий фрагмент аналізатора становить близько 55 кБ. Синхронне завантаження цього затримує початковий рендеринг сторінки та погіршує First Contentful Paint (FCP).
Щоб запобігти блокуванню інтерфейсу користувача, Intlayer інтегрується з API Suspense від React. Він завантажує аналізатор у фоновому режимі та створює Promise під час завантаження.
Оберніть будь-який компонент, що відображає Intlayer Markdown, у межу <Suspense>. Це показує локалізований резервний стан під час завантаження фрагмента, дозволяючи решті вашого DOM відображатися негайно.
Попередження: Якщо ви не надасте межу <Suspense>, React призупинить рендеринг на кореневому рівні або заблокує рендеринг всього дерева компонентів, доки фрагмент у 55 кБ не буде повністю завантажений.
У маршрутизаторі Next.js App Router ви можете використовувати або React Suspense для клієнтських компонентів, або файл loading.tsx для серверних компонентів.
Angular не має API Suspense. Використовуйте відкладені представлення (@defer) в Angular для обробки вмісту Markdown із відкладеним завантаженням (потрібен Angular 17+).
my.component.ts
Копіювати код
Скопіюйте код у буфер обміну
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");}
Рендеринг на стороні сервера (SSR) та гідратація
У порівнянні з іншими парсерами Markdown, такими як remark / rehype, Intlayer Markdown не має залежностей і працює як на клієнті, так і на сервері.
Однак Intlayer оптимізує синтаксичний аналіз для фреймворків серверного рендерингу (SSR) (таких як Next.js App Router, React Router, Nuxt, SvelteKit тощо).
Замість надсилання необроблених рядків Markdown клієнту та їх аналізу в браузері (що призводить до зниження продуктивності), Intlayer дозволяє попередньо проаналізувати Markdown в абстрактне синтаксичне дерево (AST) на сервері.
Ви можете використовувати функцію parseMarkdown з пакету Intlayer вашого фреймворку на стороні сервера для генерації серіалізованого AST (об'єкта ParsedMarkdown) і передачі його безпосередньо на фронтенд. Всі утиліти рендерингу Intlayer (такі як <MarkdownRenderer>, useMarkdownRenderer тощо) автоматично приймають цей об'єкт AST і плавно рендерять його.
Приклад в архітектурі Сервер/Клієнт
server.ts
Копіювати код
Скопіюйте код у буфер обміну
import { parseMarkdown } from "react-intlayer/markdown";// 1. На сервері: перетворити markdown на серіалізоване ASTexport const loader = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Повернути AST клієнту у форматі JSON return Response.json({ content: ast });};
client.tsx
Копіювати код
Скопіюйте код у буфер обміну
import { useLoaderData } from "react-router";import { MarkdownRenderer } from "react-intlayer/markdown";// 2. На клієнті: відрендерити AST безпосередньо без повторного аналізуexport default function Page() { const { content } = useLoaderData(); // Рендерер приймає або необроблений рядок, або проаналізоване AST return <MarkdownRenderer content={content} />;}
app/page.tsx
Копіювати код
Скопіюйте код у буфер обміну
import { parseMarkdown } from "next-intlayer/markdown";import { MarkdownRenderer } from "next-intlayer/markdown";export default async function Page() { // 1. Перетворити markdown на серіалізоване AST на сервері const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // 2. Відрендерити AST безпосередньо // У серверному компоненті це працює безшовно і передає AST// безпосередньо в базові клієнтські компоненти, якщо це необхідно. return <MarkdownRenderer content={ast} />;}
pages/index.vue
Копіювати код
Скопіюйте код у буфер обміну
<script setup lang="ts">import { parseMarkdown } from "vue-intlayer/markdown";import { MarkdownRenderer } from "vue-intlayer/markdown";// 1. Отримати та перетворити markdown на AST на серверіconst { data: ast } = await useAsyncData('markdown', () => { const markdownString = "## My title \n\nLorem Ipsum"; return parseMarkdown(markdownString);});</script><template> <!-- 2. На клієнті: відрендерити AST безпосередньо без повторного аналізу --> <MarkdownRenderer :content="ast" /></template>
+page.server.ts
Копіювати код
Скопіюйте код у буфер обміну
import { parseMarkdown } from "svelte-intlayer/markdown";// 1. На сервері: перетворити markdown на серіалізоване ASTexport const load = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Повернути AST клієнту return { content: ast };};
+page.svelte
Копіювати код
Скопіюйте код у буфер обміну
<script lang="ts"> import { MarkdownRenderer } from "svelte-intlayer/markdown"; export let data;</script><!-- 2. На клієнті: відрендерити AST безпосередньо без повторного аналізу --><MarkdownRenderer value={data.content} />
Angular SSR зазвичай отримує дані на сервері під час початкового завантаження та виконує гідратацію на клієнті. Ви можете використовувати резолвери для передачі AST.
app.resolver.ts
Копіювати код
Скопіюйте код у буфер обміну
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. На сервері: перетворити markdown на серіалізоване AST return parseMarkdown(markdownString); }}
app.component.ts
Копіювати код
Скопіюйте код у буфер обміну
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. На клієнті: відрендерити AST безпосередньо без повторного аналізу this.route.data.subscribe((data) => { this.renderedMarkdown = this.markdownService.renderMarkdown( data.markdownAst ) as string; }); }}
Цей підхід гарантує, що логіка аналізу Markdown повністю виконується на сервері, що значно скорочує час виконання на стороні клієнта та підвищує швидкість початкової гідратації.
Довідник опцій
Ці параметри можна передати до MarkdownProvider, MarkdownRenderer, useMarkdownRenderer та renderMarkdown.
Показати весь вміст таблиці
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
Option
Type
Default
Опис
forceBlock
boolean
false
Примушує вивід обгортатися блочним елементом (наприклад, <div>).
forceInline
boolean
false
Примушує вивід обгортатися вбудованим елементом (наприклад, <span>).
tagfilter
boolean
true
Увімкнює фільтр тегів GitHub для підвищення безпеки шляхом видалення небезпечних тегів HTML.
preserveFrontmatter
boolean
false
Якщо true, початкові метадані (frontmatter) на початку рядка Markdown не будуть видалені.
components
Overrides
{}
Карта тегів HTML до власних компонентів (наприклад, { h1: MyHeading }).
wrapper
Component
null
Спеціальний компонент для обгортання відображеного Markdown.
renderMarkdown
Function
null
Власна функція рендерингу для повної заміни компілятора Markdown за замовчуванням.