\n\n \n \n \n ```\n\n Configure globalmente a través del plugin `intlayerMarkdown` (admite componentes MDX personalizados):\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), // Componente MDX\n },\n });\n ```\n\n > Si el plugin `intlayerMarkdown` no está instalado, Intlayer renderizará utilizando el compilador predeterminado.\n\n También puede proporcionar anulaciones locales para nodos específicos usando el método `.use()`:\n\n ```vue\n h('h1', { style: { color: 'red' } }, props.children),\n })\" />\n ```\n\n Puede recuperar el Markdown como cadena:\n\n ```vue\n {{ myMarkdownContent.value }}\n {{ String(myMarkdownContent) }}\n {{ myMarkdownContent.toString() }}\n ```\n\n Y puede acceder a los metadatos de su markdown así:\n\n ```vue\n \n \n ```\n\n \n \n Svelte renderiza el Markdown como una cadena HTML por defecto. Use `{@html}` para renderizarlo.\n\n ```svelte fileName=\"App.svelte\"\n \n\n \n {@html $content.myMarkdownContent}\n \n ```\n\n > Si `MarkdownProvider` no está presente, Intlayer renderizará el markdown usando el compilador por defecto.\n\n También puede proporcionar anulaciones locales para nodos específicos usando el método `.use()`:\n\n ```svelte\n {@html $content.myMarkdownContent.use({ ... })}\n ```\n\n Puede recuperar el Markdown como cadena:\n\n ```svelte\n {$content.myMarkdownContent.value}\n {String($content.myMarkdownContent)}\n {$content.myMarkdownContent.toString()}\n ```\n\n Y puede acceder a los metadatos de su markdown así:\n\n ```svelte\n {$content.myMarkdownContent.metadata}\n {$content.myMarkdownContent.metadata.title}\n ```\n\n \n \n Preact soporta los nodos Markdown directamente en 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) => , // Componente MDX\n }}\n >\n \n \n );\n ```\n\n > Si `MarkdownProvider` no está presente, Intlayer renderizará el markdown usando el analizador predeterminado de Markdown a JSX.\n\n También puede proporcionar anulaciones locales para nodos específicos usando el método `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: ({ children }) =>
{children}
,\n })}\n ```\n\n Puede recuperar el Markdown como cadena:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Y puede acceder a los metadatos de su markdown así:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Solid soporta los nodos Markdown directamente en 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) => , // Componente MDX\n }}\n >\n \n \n );\n ```\n\n > Si `MarkdownProvider` no está presente, Intlayer renderizará el markdown usando el analizador predeterminado de Markdown a JSX.\n\n También puede proporcionar anulaciones locales para nodos específicos usando el método `.use()`:\n\n ```tsx\n {myMarkdownContent.use({\n h1: (props) =>
{props.children}
,\n })}\n ```\n\n Puede recuperar el Markdown como cadena:\n\n ```tsx\n {myMarkdownContent.value}\n {String(myMarkdownContent)}\n {myMarkdownContent.toString()}\n ```\n\n Y puede acceder a los metadatos de su markdown así:\n\n ```tsx\n {myMarkdownContent.metadata}\n {myMarkdownContent.metadata.title}\n ```\n\n \n \n Angular utiliza la directiva `[innerHTML]` para renderizar contenido 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 > Si el proveedor IntlayerMarkdown no está configurado, Intlayer renderizará utilizando el compilador predeterminado.\n\n También puede proporcionar anulaciones locales para nodos específicos usando el método `.use()`:\n\n ```typescript\n content().myMarkdownContent.use({\n h1: { class: \"text-3xl font-bold\" },\n })\n ```\n\n Puede recuperar el Markdown como cadena:\n\n ```typescript\n content().myMarkdownContent.value\n String(content().myMarkdownContent)\n content().myMarkdownContent.toString()\n ```\n\n Y puede acceder a los metadatos de su markdown así:\n\n ```typescript\n content().myMarkdownContent.metadata\n content().myMarkdownContent.metadata.title\n ```\n\n \n\n\n### 2. Utilidades Auxiliares (Solo Cadenas Markdown)\n\nEstas utilidades renderizan **únicamente cadenas Markdown puras** y son independientes de `useIntlayer`. Úselas cuando necesite renderizar Markdown de fuentes que no sean sus diccionarios.\n\n\n \n \n #### Componente ``\n\n Renderiza una cadena Markdown con opciones específicas.\n\n ```tsx\n import { MarkdownRenderer } from \"react-intlayer/markdown\";\n\n \n {\"# Mi Título\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Obtenga una función de renderizado preconfigurada.\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(\"# Mi Título\");\n ```\n\n #### Utilidad `renderMarkdown()`\n Utilidad independiente para renderizar fuera de los componentes.\n\n ```tsx\n import { renderMarkdown } from \"react-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Mi Título\", { forceBlock: true });\n ```\n\n \n \n \n #### Componente ``\n\n Renderiza una cadena Markdown con opciones específicas.\n\n ```tsx\n import { MarkdownRenderer } from \"next-intlayer/markdown\";\n\n \n {\"# Mi Título\"}\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n Obtenga una función de renderizado preconfigurada.\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(\"# Mi Título\");\n ```\n\n #### Utilidad `renderMarkdown()`\n Utilidad independiente para renderizar fuera de los componentes.\n\n ```tsx\n import { renderMarkdown } from \"next-intlayer/markdown\";\n\n const jsx = renderMarkdown(\"# Mi Título\", { forceBlock: true });\n ```\n\n \n \n\n #### Componente ``\n\n ```vue\n \n\n \n \n \n ```\n\n \n \n\n #### Componente ``\n\n ```svelte\n \n\n \n ```\n\n #### Hook `useMarkdownRenderer()`\n\n ```svelte\n \n\n {@html render(\"# Mi Título\")}\n ```\n\n #### Utilidad `renderMarkdown()`\n\n ```svelte\n \n\n {@html renderMarkdown(\"# Mi Título\")}\n ```\n\n \n \n #### Componente ``\n\n ```tsx\n import { MarkdownRenderer } from \"preact-intlayer/markdown\";\n\n \n {\"# Mi Título\"}\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 #### Servicio `IntlayerMarkdownService`\n Renderiza una cadena Markdown usando el servicio.\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## Configuración Global con `MarkdownProvider`\n\n`MarkdownProvider` (o su equivalente en el framework) configura el proceso de renderización Markdown para toda su aplicación. Esto se aplica tanto a la renderización automática de `useIntlayer` como a las utilidades auxiliares. Las opciones configuradas aquí son las predeterminadas — `.use()` las anula a nivel de nodo.\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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\n\n \n \n\n ```svelte fileName=\"App.svelte\"\n \n\n \n \n \n ```\n\n\n > MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. ``) se resuelve contra el mapeo de `components`.\n\n También puede usar su propio renderizador de 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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\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 > Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.\n\n \n\n\n## Suspense\n\nEl renderizador de Markdown de Intlayer se carga dinámicamente. Aunque está optimizado, el fragmento (chunk) del analizador subyacente es de aproximadamente 55 kb. Cargar esto sincrónicamente retrasa la representación inicial de la página y degrada el First Contentful Paint (FCP).\n\nPara evitar el bloqueo de la interfaz de usuario, Intlayer se integra con la API Suspense de React. Recupera el analizador en segundo plano y arroja una Promesa durante la descarga.\n\nEnvuelva cualquier componente que represente Intlayer Markdown en un límite ``. Esto muestra un estado de retroceso localizado mientras se descarga el fragmento, permitiendo que el resto de su DOM se represente de inmediato.\n\nAdvertencia: Si no proporciona un límite ``, React suspenderá en el nivel raíz o bloqueará la representación de todo el árbol de componentes hasta que el fragmento de 55 kb esté completamente cargado.\n\n\n \n\nEn Next.js App Router, puede usar React `Suspense` para componentes del cliente o un archivo `loading.tsx` para componentes del servidor.\n\n**Componente de cliente:**\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**Componente de servidor con `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 tiene un componente `` incorporado. Envuelva el componente que representa contenido Markdown en un límite ``.\n\n```vue fileName=\"MyComponent.vue\"\n\n\n\n \n \n \n
Loading...
\n \n \n\n```\n\n \n \n\nSvelte no tiene un equivalente a la API Suspense. Utilice un bloque `{#await}` para manejar la representación asíncrona del contenido 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 admite la API Suspense de React a través de `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 tiene su propio componente `` de `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 no tiene una API Suspense. Utilice las vistas diferibles de Angular (`@defer`) para manejar contenido Markdown cargado de forma diferida (requiere 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## Renderizado en el Lado del Servidor (SSR) e Hidratación\n\nEn comparación con otros analizadores de Markdown como remark / rehype, Intlayer Markdown no tiene dependencias y se ejecuta tanto en el cliente como en el servidor.\n\nSin embargo, Intlayer optimiza el análisis para frameworks de renderizado en el lado del servidor (SSR) (como Next.js App Router, React Router, Nuxt, SvelteKit, etc.).\n\nEn lugar de enviar cadenas Markdown crudas al cliente y analizarlas en el navegador (lo que incurre en una penalización de rendimiento), Intlayer le permite preanalizar el Markdown en un Árbol de Sintaxis Abstracta (AST) en el servidor.\n\nPuede usar la función `parseMarkdown` del paquete Intlayer de su framework en el lado del servidor para generar un AST serializable (objeto `ParsedMarkdown`) y pasarlo directamente al frontend. Todas las utilidades de renderizado de Intlayer (como ``, `useMarkdownRenderer`, etc.) aceptan automáticamente este objeto AST y lo renderizan sin problemas.\n\n### Ejemplo en una Arquitectura Servidor/Cliente\n\n\n \n\n ```tsx fileName=\"server.ts\"\n import { parseMarkdown } from \"react-intlayer/markdown\";\n\n // 1. En el servidor: Analizar el markdown en un AST serializable\n export const loader = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Devolver el AST como JSON al cliente\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. En el cliente: Renderizar el AST directamente sin volver a analizar\n export default function Page() {\n const { content } = useLoaderData();\n\n // El renderizador acepta tanto una cadena cruda como el AST analizado\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. Analizar el markdown en un AST serializable en el servidor\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // 2. Renderizar el AST directamente\n // En un Componente de Servidor, esto funciona sin problemas y pasa el AST\n // directamente a los componentes de cliente subyacentes si es necesario.\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. En el servidor: Analizar el markdown en un AST serializable\n export const load = async () => {\n const markdownString = \"## My title \\n\\nLorem Ipsum\";\n const ast = parseMarkdown(markdownString);\n\n // Devolver el AST al cliente\n return { content: ast };\n };\n ```\n\n ```svelte fileName=\"+page.svelte\"\n \n\n \n \n ```\n\n \n \n\n El SSR de Angular normalmente resuelve los datos en el servidor durante la carga inicial y se hidrata en el cliente. Puede usar solucionadores para pasar el AST.\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. En el servidor: Analizar el markdown en un AST serializable\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. En el cliente: Renderizar el AST directamente sin volver a analizar\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\nEste patrón garantiza que la lógica de análisis de Markdown se ejecute completamente en el servidor, lo que reduce significativamente el tiempo de ejecución en el cliente y mejora la velocidad de hidratación inicial.\n\n## Referencia de opciones\n\nEstas opciones se pueden pasar a `MarkdownProvider`, `MarkdownRenderer`, `useMarkdownRenderer` y `renderMarkdown`.\n\n| Option | Type | Default | Descripción |\n| :-------------------- | :---------- | :------ | :--------------------------------------------------------------------------------------------------------------- |\n| `forceBlock` | `boolean` | `false` | Fuerza la salida para que esté envuelta en un elemento de nivel de bloque (ej. `
`). |\n| `forceInline` | `boolean` | `false` | Fuerza la salida para que esté envuelta en un elemento en línea (ej. ``). |\n| `tagfilter` | `boolean` | `true` | Habilita el GitHub Tag Filter para mejorar la seguridad eliminando etiquetas HTML peligrosas. |\n| `preserveFrontmatter` | `boolean` | `false` | Si es `true`, no se eliminará el frontmatter al principio de la cadena Markdown. |\n| `components` | `Overrides` | `{}` | Un mapa de etiquetas HTML a componentes personalizados (ej. `{ h1: MyHeading }`). |\n| `wrapper` | `Component` | `null` | Un componente personalizado para envolver el Markdown renderizado. |\n| `renderMarkdown` | `Function` | `null` | Una función de renderizado personalizada para reemplazar completamente el compilador de Markdown predeterminado. |\n","description":"Aprenda cómo declarar y usar contenido Markdown en su sitio web multilingüe con Intlayer. Siga los pasos de esta documentación en línea para integrar Markdown sin problemas en su proyecto.","url":"https://intlayer.org/es/doc/concept/content/markdown","datePublished":"2025-02-07","dateModified":"2026-05-19","version":"8.11.0","keywords":"Markdown, Internacionalización, Documentación, Intlayer, Next.js, JavaScript, React","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Desarrolladores, Gestores de Contenido"}}
Copiar el Markdown del documento a la portapapeles
Markdown / Contenido de Texto Enriquecido
Intlayer admite contenido de texto enriquecido definido mediante la sintaxis Markdown. Esto le permite escribir y mantener fácilmente contenido con formato enriquecido, como blogs, artículos y mucho más.
Declarar Contenido Markdown
Puede declarar contenido Markdown usando la función md o simplemente como una cadena de texto (si contiene sintaxis Markdown).
A partir de la versión 8.10.0, puede declarar contenido Markdown directamente en archivos .content.md. Intlayer detectará y analizará automáticamente el contenido Markdown.
markdown-file.en.content.md
Copiar código
Copiar el código al portapapeles
---key: my-markdown-contentdescription: Mi contenidolocale: en---# Mi contenidoAquí hay un ejemplo de contenido markdown
El campo locale en el front-matter es el campo que define el idioma del contenido. Es opcional. Si no se proporciona, Intlayer utilizará el idioma por defecto, que también se usa como idioma de respaldo si no hay traducción disponible para un idioma específico.
Use la función md para declarar explícitamente contenido Markdown. Esto es útil si desea asegurarse de que una cadena se trate como Markdown incluso si no contiene sintaxis evidente.
markdownDictionary.content.ts
Copiar código
Copiar el código al portapapeles
import { md, type Dictionary } from "intlayer";const markdownDictionary = { key: "app", content: { myMarkdownContent: md("## Mi título \n\nLorem Ipsum"), },} satisfies Dictionary;export default markdownDictionary;
Importe archivos .md directamente usando la función file.
Si la cadena contiene indicadores comunes de Markdown (como encabezados, listas, enlaces, etc.), Intlayer la transformará automáticamente.
markdownDictionary.content.ts
Copiar código
Copiar el código al portapapeles
export default { key: "app", contentAutoTransformation: true, // Habilitar detección automática de contenido Markdown - Se puede configurar globalmente en intlayer.config.ts content: { myMarkdownContent: "## Mi título \n\nLorem Ipsum", },};
Renderización de Markdown
Intlayer proporciona dos formas independientes de renderizar Markdown:
A través de useIntlayer
— Intlayer transforma automáticamente el nodo md en la salida nativa del framework (JSX, VNode, cadena HTML).
El Frontmatter se analiza y expone como .metadata. Puede anular la renderización en dos niveles — globalmente con MarkdownProvider (o el equivalente en el framework) y localmente por nodo con .use(). Ambos pueden combinarse; .use() tiene prioridad sobre MarkdownProvider, el cual tiene prioridad sobre el predeterminado.
Utilidades auxiliares — <MarkdownRenderer />, useMarkdownRenderer(), y renderMarkdown() son herramientas independientes que aceptan únicamente cadenas Markdown puras. Son independientes de useIntlayer y no funcionan con los nodos decorados que este retorna.
La renderización de Markdown admite MDX — use cualquier componente JSX/framework por su nombre directamente dentro de su Markdown.
1. Renderización Automática (a través de useIntlayer)
Los nodos Markdown se pueden renderizar directamente como JSX.
Estas utilidades renderizan únicamente cadenas Markdown puras y son independientes de useIntlayer. Úselas cuando necesite renderizar Markdown de fuentes que no sean sus diccionarios.
Componente <MarkdownRenderer />
Renderiza una cadena Markdown con opciones específicas.
tsx
Copiar código
Copiar el código al portapapeles
import { MarkdownRenderer } from "react-intlayer/markdown";<MarkdownRenderer forceBlock={true} tagfilter={true}> {"# Mi Título"}</MarkdownRenderer>
Hook useMarkdownRenderer()
Obtenga una función de renderizado preconfigurada.
Utilidad independiente para renderizar fuera de los componentes.
tsx
Copiar código
Copiar el código al portapapeles
import { renderMarkdown } from "next-intlayer/markdown";const jsx = renderMarkdown("# Mi Título", { forceBlock: true });
Componente <MarkdownRenderer />
vue
Copiar código
Copiar el código al portapapeles
<script setup>import { MarkdownRenderer } from "vue-intlayer/markdown";</script><template> <MarkdownRenderer :forceBlock="true" content="# Mi Título" /></template>
Componente <MarkdownRenderer />
svelte
Copiar código
Copiar el código al portapapeles
<script lang="ts">import { MarkdownRenderer } from "svelte-intlayer/markdown";</script><MarkdownRenderer forceBlock={true} value="# Mi Título" />
Hook useMarkdownRenderer()
svelte
Copiar código
Copiar el código al portapapeles
<script lang="ts">import { useMarkdownRenderer } from "svelte-intlayer/markdown";const render = useMarkdownRenderer();</script>{@html render("# Mi Título")}
Utilidad renderMarkdown()
svelte
Copiar código
Copiar el código al portapapeles
<script lang="ts">import { renderMarkdown } from "svelte-intlayer/markdown";</script>{@html renderMarkdown("# Mi Título")}
Componente <MarkdownRenderer />
tsx
Copiar código
Copiar el código al portapapeles
import { MarkdownRenderer } from "preact-intlayer/markdown";<MarkdownRenderer forceBlock={true}> {"# Mi Título"}</MarkdownRenderer>
Hook useMarkdownRenderer()
tsx
Copiar código
Copiar el código al portapapeles
import { useMarkdownRenderer } from "preact-intlayer/markdown";const render = useMarkdownRenderer();return <div>{render("# Mi Título")}</div>;
Utilidad renderMarkdown()
tsx
Copiar código
Copiar el código al portapapeles
import { renderMarkdown } from "preact-intlayer/markdown";return <div>{renderMarkdown("# Mi Título")}</div>;
Componente <MarkdownRenderer />
tsx
Copiar código
Copiar el código al portapapeles
import { MarkdownRenderer } from "solid-intlayer/markdown";<MarkdownRenderer forceBlock={true}> {"# Mi Título"}</MarkdownRenderer>
Hook useMarkdownRenderer()
tsx
Copiar código
Copiar el código al portapapeles
import { useMarkdownRenderer } from "solid-intlayer/markdown";const render = useMarkdownRenderer();return <div>{render("# Mi Título")}</div>;
Utilidad renderMarkdown()
tsx
Copiar código
Copiar el código al portapapeles
import { renderMarkdown } from "solid-intlayer/markdown";return <div>{renderMarkdown("# Mi Título")}</div>;
Servicio IntlayerMarkdownService
Renderiza una cadena Markdown usando el servicio.
typescript
Copiar código
Copiar el código al portapapeles
import { IntlayerMarkdownService } from "angular-intlayer/markdown";export class MyComponent { constructor(private markdownService: IntlayerMarkdownService) {} renderMarkdown(markdown: string) { return this.markdownService.renderMarkdown(markdown); }}
Configuración Global con MarkdownProvider
MarkdownProvider (o su equivalente en el framework) configura el proceso de renderización Markdown para toda su aplicación. Esto se aplica tanto a la renderización automática de useIntlayer como a las utilidades auxiliares. Las opciones configuradas aquí son las predeterminadas — .use() las anula a nivel de nodo.
MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
AppProvider.tsx
Copiar código
Copiar el código al portapapeles
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>);
Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.
MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
AppProvider.tsx
Copiar código
Copiar el código al portapapeles
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>);
Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.
MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
main.ts
Copiar código
Copiar el código al portapapeles
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");
Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.
App.svelte
Copiar código
Copiar el código al portapapeles
<script lang="ts"> import { MarkdownProvider } from "svelte-intlayer/markdown"; import MyHeading from "./MyHeading.svelte";</script><MarkdownProvider components={{ h1: MyHeading, }}> <slot /></MarkdownProvider>
MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.
AppProvider.tsx
Copiar código
Copiar el código al portapapeles
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 es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
MDX es compatible — cualquier nombre de componente usado dentro de su Markdown (ej. <MyCustomJSXComponent />) se resuelve contra el mapeo de components.
También puede usar su propio renderizador de markdown:
Importar su renderizador de Markdown dinámicamente es una buena manera de reducir el tamaño del bundle de su aplicación.
Suspense
El renderizador de Markdown de Intlayer se carga dinámicamente. Aunque está optimizado, el fragmento (chunk) del analizador subyacente es de aproximadamente 55 kb. Cargar esto sincrónicamente retrasa la representación inicial de la página y degrada el First Contentful Paint (FCP).
Para evitar el bloqueo de la interfaz de usuario, Intlayer se integra con la API Suspense de React. Recupera el analizador en segundo plano y arroja una Promesa durante la descarga.
Envuelva cualquier componente que represente Intlayer Markdown en un límite <Suspense>. Esto muestra un estado de retroceso localizado mientras se descarga el fragmento, permitiendo que el resto de su DOM se represente de inmediato.
Advertencia: Si no proporciona un límite <Suspense>, React suspenderá en el nivel raíz o bloqueará la representación de todo el árbol de componentes hasta que el fragmento de 55 kb esté completamente cargado.
En Next.js App Router, puede usar React Suspense para componentes del cliente o un archivo loading.tsx para componentes del servidor.
Angular no tiene una API Suspense. Utilice las vistas diferibles de Angular (@defer) para manejar contenido Markdown cargado de forma diferida (requiere Angular 17+).
my.component.ts
Copiar código
Copiar el código al portapapeles
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");}
Renderizado en el Lado del Servidor (SSR) e Hidratación
En comparación con otros analizadores de Markdown como remark / rehype, Intlayer Markdown no tiene dependencias y se ejecuta tanto en el cliente como en el servidor.
Sin embargo, Intlayer optimiza el análisis para frameworks de renderizado en el lado del servidor (SSR) (como Next.js App Router, React Router, Nuxt, SvelteKit, etc.).
En lugar de enviar cadenas Markdown crudas al cliente y analizarlas en el navegador (lo que incurre en una penalización de rendimiento), Intlayer le permite preanalizar el Markdown en un Árbol de Sintaxis Abstracta (AST) en el servidor.
Puede usar la función parseMarkdown del paquete Intlayer de su framework en el lado del servidor para generar un AST serializable (objeto ParsedMarkdown) y pasarlo directamente al frontend. Todas las utilidades de renderizado de Intlayer (como <MarkdownRenderer>, useMarkdownRenderer, etc.) aceptan automáticamente este objeto AST y lo renderizan sin problemas.
Ejemplo en una Arquitectura Servidor/Cliente
server.ts
Copiar código
Copiar el código al portapapeles
import { parseMarkdown } from "react-intlayer/markdown";// 1. En el servidor: Analizar el markdown en un AST serializableexport const loader = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Devolver el AST como JSON al cliente return Response.json({ content: ast });};
client.tsx
Copiar código
Copiar el código al portapapeles
import { useLoaderData } from "react-router";import { MarkdownRenderer } from "react-intlayer/markdown";// 2. En el cliente: Renderizar el AST directamente sin volver a analizarexport default function Page() { const { content } = useLoaderData(); // El renderizador acepta tanto una cadena cruda como el AST analizado return <MarkdownRenderer content={content} />;}
app/page.tsx
Copiar código
Copiar el código al portapapeles
import { parseMarkdown } from "next-intlayer/markdown";import { MarkdownRenderer } from "next-intlayer/markdown";export default async function Page() { // 1. Analizar el markdown en un AST serializable en el servidor const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // 2. Renderizar el AST directamente // En un Componente de Servidor, esto funciona sin problemas y pasa el AST// directamente a los componentes de cliente subyacentes si es necesario. return <MarkdownRenderer content={ast} />;}
pages/index.vue
Copiar código
Copiar el código al portapapeles
<script setup lang="ts">import { parseMarkdown } from "vue-intlayer/markdown";import { MarkdownRenderer } from "vue-intlayer/markdown";// 1. Obtener y analizar el markdown en un AST en el servidorconst { data: ast } = await useAsyncData('markdown', () => { const markdownString = "## My title \n\nLorem Ipsum"; return parseMarkdown(markdownString);});</script><template> <!-- 2. En el cliente: Renderizar el AST directamente sin volver a analizar --> <MarkdownRenderer :content="ast" /></template>
+page.server.ts
Copiar código
Copiar el código al portapapeles
import { parseMarkdown } from "svelte-intlayer/markdown";// 1. En el servidor: Analizar el markdown en un AST serializableexport const load = async () => { const markdownString = "## My title \n\nLorem Ipsum"; const ast = parseMarkdown(markdownString); // Devolver el AST al cliente return { content: ast };};
+page.svelte
Copiar código
Copiar el código al portapapeles
<script lang="ts"> import { MarkdownRenderer } from "svelte-intlayer/markdown"; export let data;</script><!-- 2. En el cliente: Renderizar el AST directamente sin volver a analizar --><MarkdownRenderer value={data.content} />
El SSR de Angular normalmente resuelve los datos en el servidor durante la carga inicial y se hidrata en el cliente. Puede usar solucionadores para pasar el AST.
app.resolver.ts
Copiar código
Copiar el código al portapapeles
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. En el servidor: Analizar el markdown en un AST serializable return parseMarkdown(markdownString); }}
app.component.ts
Copiar código
Copiar el código al portapapeles
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. En el cliente: Renderizar el AST directamente sin volver a analizar this.route.data.subscribe((data) => { this.renderedMarkdown = this.markdownService.renderMarkdown( data.markdownAst ) as string; }); }}
Este patrón garantiza que la lógica de análisis de Markdown se ejecute completamente en el servidor, lo que reduce significativamente el tiempo de ejecución en el cliente y mejora la velocidad de hidratación inicial.
Referencia de opciones
Estas opciones se pueden pasar a MarkdownProvider, MarkdownRenderer, useMarkdownRenderer y renderMarkdown.
Mostrar todo el contenido de la tabla
Abrir la tabla en una ventana flotante para ver todo el contenido claramente
Option
Type
Default
Descripción
forceBlock
boolean
false
Fuerza la salida para que esté envuelta en un elemento de nivel de bloque (ej. <div>).
forceInline
boolean
false
Fuerza la salida para que esté envuelta en un elemento en línea (ej. <span>).
tagfilter
boolean
true
Habilita el GitHub Tag Filter para mejorar la seguridad eliminando etiquetas HTML peligrosas.
preserveFrontmatter
boolean
false
Si es true, no se eliminará el frontmatter al principio de la cadena Markdown.
components
Overrides
{}
Un mapa de etiquetas HTML a componentes personalizados (ej. { h1: MyHeading }).
wrapper
Component
null
Un componente personalizado para envolver el Markdown renderizado.
renderMarkdown
Function
null
Una función de renderizado personalizada para reemplazar completamente el compilador de Markdown predeterminado.