Contenido Multilingüe
El cargador de contenido multilingüe te permite escribir todas las variantes de idioma de una entrada de contenido en un solo archivo markdown, usando frontmatter YAML para campos estructurados y marcadores de comentarios HTML para el contenido del cuerpo.
Formato del archivo markdown
---name: en: Model 165 es: Modelo 165slugs: en: model-165 es: modelo-165image: /images/model-165.jpgdescription: en: Compact sauna solution es: Solución de sauna compactapublished: 2024-01-01---
English body content with **markdown**.
<!-- locale:es -->
Contenido en español con **markdown**.Reglas del frontmatter
- Campos localizados usan un objeto con claves de idioma:
{ en: "...", es: "..." } - Campos compartidos son valores simples:
image: /images/model-165.jpg - Puedes mezclar ambos en el mismo frontmatter
Reglas del cuerpo
- El contenido antes del primer marcador pertenece al idioma predeterminado
- Cada marcador
<!-- locale:XX -->inicia una nueva sección de idioma - Las secciones se parsean con
markedy se devuelven como HTML en un registrobodyHtml
Configurando el loader
1. Define la colección
import { defineCollection, z } from 'astro:content';import { createMultilingualLoader } from '@otrodigital/astro-i18n-next';
const saunas = defineCollection({ loader: createMultilingualLoader({ contentDir: 'src/content/saunas' }), schema: z.object({ name: z.object({ en: z.string(), es: z.string().optional() }), slugs: z.object({ en: z.string(), es: z.string().optional() }), image: z.string(), description: z.object({ en: z.string(), es: z.string().optional() }), published: z.coerce.date(), bodyHtml: z.record(z.string()).optional(), }),});
export const collections = { saunas };2. Usa en plantillas
---import { getCollection } from 'astro:content';import { localized } from 'virtual:i18n';
const locale = Astro.locals.locale;const saunas = await getCollection('saunas');---
{saunas.map(sauna => ( <article> <h2>{localized(sauna.data.name, locale)}</h2> <p>{localized(sauna.data.description, locale)}</p> <div set:html={sauna.data.bodyHtml?.[locale]} /> </article>))}El helper localized()
La función localized() extrae el valor específico del idioma de un objeto de campo multilingüe, con fallback al idioma predeterminado:
import { localized } from 'virtual:i18n';
localized({ en: 'Hello', es: 'Hola' }, 'es'); // "Hola"localized({ en: 'Hello' }, 'es'); // "Hello" (fallback)Funciona con cualquier tipo de valor — strings, arrays, objetos.
Auto-descubrimiento de slugs
Cuando especificas contentDirs en la configuración de createI18n, la integración lee automáticamente el campo slugs del frontmatter de cada archivo markdown para construir el mapa de slugs. Esto significa que localePath y switchLocalePath pueden traducir URLs de contenido sin configuración adicional.