Saltar al contenido
Todos los artículos

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

This article is also available in English.

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.