Saltearse al contenido

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:

IdiomaNombre del idiomaPrefijo de URLAbreviatura en la interfaz
简体中文Chino simplificado (predeterminado)sin prefijoZH
繁體中文Chino tradicional/zh-tw/TW
EnglishInglés/en/EN
日本語Japonés/ja/JA
한국어Coreano/ko/KO
EspañolEspañol/es/ES
FrançaisFrancés/fr/FR
DeutschAlemán/de/DE
РусскийRuso/ru/RU
PortuguêsPortugué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

  1. Localice el botón de idioma a la derecha de la barra de navegación superior (muestra la abreviatura del idioma actual, como ZH);
  2. Al hacer clic en el botón, el menú desplegable enumera los 10 idiomas;
  3. Haga clic en el idioma de destino (por ejemplo, English o 日本語);
  4. 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.

Efecto real anotado del menú desplegable de cambio de idioma al expandirse: ① botón de idioma ② lista de idiomas ③ idioma actual

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).

Diagrama del mecanismo de funcionamiento del cambio de idioma

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:

  1. Directorios de contenido divididos por idioma: los documentos del idioma predeterminado van en src/content/docs/ (chino simplificado) y los demás idiomas en src/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» es src/content/docs/en/canvas/i18n.md;
  2. Generación de páginas en todos los idiomas durante la compilación: astro build lee la configuración locales de astro.config.mjs y genera un juego completo de páginas estáticas para cada idioma;
  3. 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;
  4. Localización automática de los enlaces internos del cuerpo: el plugin rehypeLocalizeInternalLinks de la canalización de compilación añade automáticamente el prefijo del idioma actual a los enlaces internos /canvas/xxx presentes en el cuerpo traducido;
  5. 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.
  6. Las imágenes del texto se resuelven por idioma: el plugin rehypeLocalizeDiagramImages reescribe /images/canvas/<archivo> en las traducciones como /images/canvas/<idioma>/<archivo>, y los archivos de cada idioma viven en public/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;
  7. Avisos y notas al pie siguen el idioma de la página: rehypeLocalizeAsides y rehypeLocalizeFootnotes reescriben 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;
  8. hreflang y la página 404: al terminar la compilación, hreflangXDefault() añade a cada página un hreflang="x-default" que apunta a la versión en chino simplificado, y src/pages/404.astro reutiliza 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):

  1. Registrar la ruta del idioma: añadir it: { label: 'Italiano', lang: 'it' } en locales de astro.config.mjs;
  2. Completar los textos de la barra lateral: en SIDEBAR_I18N del mismo archivo, añadir la traducción it para todos los grupos y entradas;
  3. Completar los textos de la interfaz: registrar el idioma (código, nombre, abreviatura, prefijo de URL) en SUPPORTED_LANGUAGES de src/utils/i18n.ts y añadir las cadenas de interfaz de ese idioma en UI_TRANSLATIONS;
  4. 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, crea public/images/canvas/it/ con archivos del mismo nombre: las páginas los usan solos.
  5. Volver a compilar: ejecutar pnpm run build y se generarán las páginas del idioma nuevo y su índice de búsqueda. Al terminar, ejecuta node scripts/audit-i18n.mjs y node scripts/check-localized-images.mjs para 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:

src/utils/i18n.ts
// El diccionario se organiza en dos niveles «idioma → clave de cadena»,
// igual que el orden de lectura de getTranslation
export 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.