Soporte multilingüe y cambio de idioma
EpoCanvas Docs incorpora de serie un multilingüismo completo a nivel de contenido: los textos de la interfaz (barra de navegación, barra lateral, indicaciones de búsqueda, etc.) y el cuerpo de cada documento están disponibles en 10 idiomas independientes. Cuando el lector elige un idioma en la esquina superior derecha de la página, salta a la versión del mismo artículo en ese idioma, cambiando a la vez el cuerpo y la interfaz.
Lista de idiomas admitidos
El sitio ofrece actualmente 10 idiomas, con el chino simplificado como idioma predeterminado:
| Idioma | Nombre del idioma | Prefijo de URL | Abreviatura en la interfaz |
|---|---|---|---|
| 简体中文 | Chino simplificado (predeterminado) | sin prefijo | ZH |
| 繁體中文 | Chino tradicional | /zh-tw/ | TW |
| English | Inglés | /en/ | EN |
| 日本語 | Japonés | /ja/ | JA |
| 한국어 | Coreano | /ko/ | KO |
| Español | Español | /es/ | ES |
| Français | Francés | /fr/ | FR |
| Deutsch | Alemán | /de/ | DE |
| Русский | Ruso | /ru/ | RU |
| Português | Portugués | /pt/ | PT |
La lista de idiomas está definida en SUPPORTED_LANGUAGES de src/utils/i18n.ts, y el registro de rutas de idioma en la configuración locales de astro.config.mjs; ambas deben mantenerse coherentes.
Cómo cambiar de idioma
- Localice el botón de idioma a la derecha de la barra de navegación superior (muestra la abreviatura del idioma actual, como
ZH); - Al hacer clic en el botón, el menú desplegable enumera los 10 idiomas;
- Haga clic en el idioma de destino (por ejemplo,
Englisho日本語); - El navegador salta a la versión del artículo actual en ese idioma; la navegación, la barra lateral, el índice y el cuerpo pasan juntos al idioma de destino.

Figura: efecto real anotado tras hacer clic en el botón de idioma en la página «Soporte multilingüe y cambio de idioma». ① botón de cambio de idioma a la derecha de la barra superior; ② menú desplegable expandido con los 10 idiomas (la lista es desplazable); ③ idioma vigente (marcado con una marca de verificación).
Figura: flujo de ejecución del cambio de idioma. Durante la compilación se genera un conjunto de páginas estáticas por idioma; al hacer clic en el botón de idioma se salta al mismo artículo en el idioma correspondiente; si alguna página carece de traducción, se muestra automáticamente el contenido en chino como fallback.
Reglas de URL
Las páginas de cada idioma tienen un prefijo de URL propio; el mismo artículo solo difiere en el prefijo entre idiomas:
/canvas/i18n/ → Chino simplificado (idioma predeterminado, sin prefijo)/en/canvas/i18n/ → Inglés/ja/canvas/i18n/ → Japonés/zh-tw/canvas/i18n/ → Chino tradicional- La información de idioma queda codificada directamente en la URL, de modo que la página tras el cambio se puede guardar en favoritos y compartir, y los buscadores pueden indexarla por idioma;
- Los enlaces internos del sitio que aparecen en la página (navegación, barra lateral, enlaces recomendados en el cuerpo) llevan automáticamente el prefijo del idioma actual, así que el lector que lee de forma continua dentro de un idioma no acaba saltando a páginas en chino;
- Cada versión de idioma es una página estática independiente generada en tiempo de compilación; el atributo
<html lang>de la página coincide con el idioma, por lo que los lectores de pantalla y las herramientas de traducción pueden identificarlo correctamente.
Qué pasa cuando falta una traducción
El sistema aplica una estrategia de “fallback al idioma predeterminado” para las traducciones ausentes: cuando un documento aún no tiene traducción a un idioma, la página de ese idioma muestra el contenido en chino simplificado predeterminado, mientras el resto de la página (navegación, barra lateral, textos de la interfaz) permanece en el idioma de destino; no aparece un error 404 ni una página en blanco.
La ventaja de esta estrategia es que al añadir documentos nuevos no hay que esperar a que estén listas las traducciones de todos los idiomas: se publica primero la versión en chino y, cuando las traducciones estén completas, basta con volver a compilar.
Cómo funciona por dentro
La capacidad multilingüe se apoya en el mecanismo de internacionalización de Astro y Starlight; el flujo de compilación es el siguiente:
- Directorios de contenido divididos por idioma: los documentos del idioma predeterminado van en
src/content/docs/(chino simplificado) y los demás idiomas ensrc/content/docs/<idioma>/, con una estructura de directorios idéntica a la del chino; por ejemplo, la versión en inglés de «Soporte multilingüe y cambio de idioma» essrc/content/docs/en/canvas/i18n.md; - Generación de páginas en todos los idiomas durante la compilación:
astro buildlee la configuraciónlocalesdeastro.config.mjsy genera un juego completo de páginas estáticas para cada idioma; - Textos de interfaz renderizados por idioma: los textos de interfaz como la navegación superior, los avisos de búsqueda o el título del índice los emiten directamente los componentes mediante
getTranslation(key, lang)en tiempo de compilación; no hay scripts de sustitución en tiempo de ejecución; - Localización automática de los enlaces internos del cuerpo: el plugin
rehypeLocalizeInternalLinksde la canalización de compilación añade automáticamente el prefijo del idioma actual a los enlaces internos/canvas/xxxpresentes en el cuerpo traducido; - Búsqueda de texto completo aislada por idioma: Pagefind crea un índice independiente para cada idioma; buscar en una página en inglés solo devuelve resultados en inglés.
- Las imágenes del texto se resuelven por idioma: el plugin
rehypeLocalizeDiagramImagesreescribe/images/canvas/<archivo>en las traducciones como/images/canvas/<idioma>/<archivo>, y los archivos de cada idioma viven enpublic/images/canvas/<idioma>/; si no hay un archivo con el mismo nombre se conserva el original, así que una imagen nueva no hace falta traducirla a las 10 lenguas a la vez; - Avisos y notas al pie siguen el idioma de la página:
rehypeLocalizeAsidesyrehypeLocalizeFootnotesreescriben los títulos de los avisos y las notas según el directorio de idioma del archivo fuente — Starlight deduce el idioma en remark a partir de la ruta absoluta, pero la compilación local le pasa una ruta relativa, y sin esto todo caería en chino; - hreflang y la página 404: al terminar la compilación,
hreflangXDefault()añade a cada página unhreflang="x-default"que apunta a la versión en chino simplificado, ysrc/pages/404.astroreutiliza el mismo diccionario para escribir su mensaje en el idioma del navegador, con un menú de idiomas que lleva a la portada de cada idioma.
Para desarrolladores: cómo añadir un idioma nuevo
Tomemos como ejemplo añadir el italiano (Italiano, código it):
- Registrar la ruta del idioma: añadir
it: { label: 'Italiano', lang: 'it' }enlocalesdeastro.config.mjs; - Completar los textos de la barra lateral: en
SIDEBAR_I18Ndel mismo archivo, añadir la traducciónitpara todos los grupos y entradas; - Completar los textos de la interfaz: registrar el idioma (código, nombre, abreviatura, prefijo de URL) en
SUPPORTED_LANGUAGESdesrc/utils/i18n.tsy añadir las cadenas de interfaz de ese idioma enUI_TRANSLATIONS; - Traducir el contenido de los documentos: crear el directorio
src/content/docs/it/y colocar las traducciones siguiendo la estructura de directorios de la versión china. Las páginas sin traducir mostrarán primero el chino como fallback y se pueden completar poco a poco; Si también quieres traducir capturas y diagramas, creapublic/images/canvas/it/con archivos del mismo nombre: las páginas los usan solos. - Volver a compilar: ejecutar
pnpm run buildy se generarán las páginas del idioma nuevo y su índice de búsqueda. Al terminar, ejecutanode scripts/audit-i18n.mjsynode scripts/check-localized-images.mjspara revisar la estructura de la traducción y las referencias de imágenes; ambas son comprobaciones obligatorias en CI.
Para desarrolladores: cómo añadir o modificar cadenas de interfaz
Al añadir un elemento de interfaz nuevo, agregue la cadena correspondiente en UI_TRANSLATIONS de src/utils/i18n.ts:
// El diccionario se organiza en dos niveles «idioma → clave de cadena»,// igual que el orden de lectura de getTranslationexport const UI_TRANSLATIONS: Record<string, Record<string, string>> = { // Paso 1: añadir la cadena en el idioma predeterminado zh-CN // (si falta, la interfaz muestra el nombre de la clave como fallback) 'zh-CN': { 'nav.plugins': '插件生态', // ...resto de cadenas existentes }, // Paso 2: añadir la traducción con la misma clave en los demás idiomas; // los idiomas sin traducir hacen fallback al chino automáticamente en: { 'nav.plugins': 'Plugins', }, ja: { 'nav.plugins': 'プラグイン', },};A continuación, llame a getTranslation en el componente pasándole el idioma actual:
---import { getLangFromLocale, getTranslation } from '../../utils/i18n';const lang = getLangFromLocale(Astro.currentLocale);---
<a href={localizedHref('/plugins/', lang)}>{getTranslation('nav.plugins', lang)}</a>Las cadenas se renderizan en tiempo de compilación como texto estático en el idioma correspondiente, sin coste en tiempo de ejecución.