Sitios estáticos bilingües con Astro: rutas, hreflang y fallbacks honestos
Cómo este sitio sirve inglés y español desde una sola base de código sin anunciar traducciones que no existen.
- Publicado
- 2 min de lectura
- Por José María Sanhueza Solovera
Este sitio se publica en inglés y en español. El inglés vive en la raíz (/blog/) y el español bajo
un prefijo (/es/blog/). Esa parte es fácil; las decisiones interesantes son qué pasa cuando una
página existe en un solo idioma.
Un archivo de ruta por página, no por idioma
El routing i18n de Astro define el esquema de URL. En lugar de duplicar cada página en
src/pages/es/, cada página existe una sola vez bajo un parámetro rest y se genera para cada idioma:
---
import { localeStaticPaths } from '../../i18n/locales';
export const getStaticPaths = localeStaticPaths;
const { locale } = Astro.props;
---
localeStaticPaths() devuelve { lang: undefined } para el inglés y { lang: 'es' } para el
español, así que la misma plantilla genera /resume/ y /es/resume/.
Las traducciones son explícitas
Los artículos son archivos en src/content/blog/<locale>/. Dos artículos son traducciones entre sí
solo si comparten un translationKey. Así el slug puede traducirse: este artículo es
/blog/bilingual-astro-sites/ en inglés y /es/blog/sitios-bilingues-con-astro/ en español.
| Señal | Se emite cuando |
|---|---|
Alternativa hreflang |
existe una traducción con la misma clave |
xhtml:link del sitemap |
la misma condición, calculada por la misma función |
| Selector de idioma | enlaza a la traducción o a una página de sección |
Fallbacks que no mienten
Cuando una página no tiene traducción, el selector de idioma sigue funcionando: apunta a la sección
equivalente en el otro idioma (por ejemplo, el índice del blog en español) y lo indica en su nombre
accesible. Nunca apunta a una URL que devolvería un 404, y la página nunca declara una alternativa
hreflang para un idioma que no tiene.
Comprobarlo en CI
Una batería de tests se ejecuta contra la carpeta dist/ ya compilada. Verifica que cada enlace
interno lleve a un archivo, que cada alternativa hreflang exista y enlace de vuelta, y que los
borradores no aparezcan en los listados, en los feeds RSS ni en el sitemap.