CategoríaContenido y búsqueda

SEO multilingüe en Astro: declarar versiones y regiones

8 minutos de lectura

Un sitio multilingüe tiene una tarea antes que cualquier otra: decirle al buscador que las URLs en inglés, portugués y español son la misma página en tres idiomas. Sin esa declaración, cada traducción es un documento aparte que compite por la misma consulta.

Por qué la relación entre las versiones va antes de la traducción

Google Search Central afirma en versiones localizadas de la página que el hreflang existe para que el buscador entienda que las páginas son variaciones localizadas del mismo contenido.

Sin la anotación, el buscador ve tres URLs con sentido parecido y ninguna relación declarada. Cada una pasa a ser candidata para la misma consulta.

No hay castigo. Lo que pasa es que el buscador elige por ti, y esa decisión suele favorecer la versión con señales más fuertes, no la versión que el lector necesita.

Idioma, región y alternativa son tres declaraciones distintas

La mayoría de los sitios mezcla las tres cosas, y ahí empieza el error.

  • La declaración de idioma es el atributo lang en el elemento html. El estándar HTML (en inglés) lo define como el idioma del contenido del elemento, y no dice nada sobre las otras versiones.
  • La declaración de región es la segunda mitad de un código como pt-BR, escrito en el formato ISO 3166-1 Alpha 2 (versiones localizadas de la página). Un código como pt solo nombra el idioma y ninguna región.
  • La declaración de alternativa es rel="alternate" hreflang, que enlaza una URL con otra. Es la única de las tres que describe una relación entre documentos.

La documentación de i18n de Astro (en inglés) usa una clave de locale como pt-br para nombrar la carpeta de la ruta. La opción i18n (en inglés) de @astrojs/sitemap convierte esa clave en atributo de idioma. La clave nombra la dirección, el atributo nombra el idioma, y los dos no tienen que ser iguales.

Cómo se escribe el hreflang y qué exige la reciprocidad

Google documenta tres formas de publicar la anotación: elementos link en el head, cabeceras HTTP de respuesta y el sitemap.

La forma en el head es esta:

<link rel="alternate" hreflang="en" href="https://www.example.com/blog/post/" />
<link rel="alternate" hreflang="pt-BR" href="https://www.example.com/pt-br/blog/post/" />
<link rel="alternate" hreflang="es" href="https://www.example.com/es/blog/post/" />
<link rel="alternate" hreflang="x-default" href="https://www.example.com/blog/post/" />

Dos reglas vienen con ella, y Google declara las dos como directrices de todos los métodos.

  • Cada versión de idioma debe listarse a sí misma y también a todas las demás versiones.
  • Las URLs alternativas deben ser completas, incluido el método de transporte.

Lo que más suele faltar es que la página se apunte a sí misma. Una página en portugués que lista inglés y español pero no a sí misma deja el conjunto incompleto, y el buscador puede descartar el grupo. Google afirma que las etiquetas que no se apuntan entre sí se ignoran.

El valor x-default marca la página para quien habla un idioma fuera de la lista. Google menciona selectores de idioma y páginas de inicio con redirección automática como el caso de uso.

Qué agrega el sitemap a la anotación

El sitemap lleva la misma relación en XML, con entradas xhtml:link que listan cada variante, incluida la propia página (versiones localizadas de la página).

<url>
  <loc>https://www.example.com/pt-br/blog/post/</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://www.example.com/blog/post/" />
  <xhtml:link rel="alternate" hreflang="pt-BR" href="https://www.example.com/pt-br/blog/post/" />
  <xhtml:link rel="alternate" hreflang="es" href="https://www.example.com/es/blog/post/" />
</url>

El protocolo del sitemap exige la declaración de namespace en urlset, escape de entidades en todo valor y codificación UTF-8.

La documentación de sitemap de Google pone un límite al lastmod: el valor se usa solo cuando es consistente y verificablemente exacto. Google ignora priority y changefreq.

En un blog, el lastmod correcto por idioma es la fecha del frontmatter de ese idioma. Sellar la fecha del build en cada URL le enseña al buscador a ignorar el campo.

El hreflang huérfano y cómo detectarlo en el build

El defecto más común es una URL alternativa que devuelve 404. Aparece cuando el slug cambia en un idioma, cuando se elimina una traducción o cuando la ruta se escribe a mano.

La página con la etiqueta sigue siendo válida, así que su informe no cambia. El grupo solo pierde un integrante.

Esa comprobación debe hacerse en el build. Después de que el sitio compila, lee el HTML generado, recoge cada href de hreflang y confirma que cada ruta existe como carpeta con un index.html.

El script es corto, y rechaza el build cuando una alternativa apunta a un archivo que nunca se generó.

Qué hacer cuando la traducción no existe

Existen tres opciones, y solo una es gratuita.

  • Publica la anotación solo para las versiones que existen. Las versiones que nunca escribiste no son versiones.
  • Evita la redirección automática al inglés. La guía de Google pide un selector de idioma en lugar de una redirección basada en el visitante.
  • Entrega una traducción real o no entregues nada. La misma guía advierte contra la traducción de texto genérico y pide una indicación clara de idioma en la página.

Una página traducida por máquina con el mismo slug es un duplicado en un idioma nuevo, y la anotación no lo repara.

Qué no resuelve el hreflang

La anotación es una afirmación sobre la relación. No es señal de posicionamiento, y no es detector de idioma.

  • Google afirma que no usa hreflang ni el atributo lang del html para detectar el idioma de una página, y usa algoritmos en su lugar.
  • El contenido duplicado de verdad sigue duplicado. Cuando dos URLs tienen el mismo texto en el mismo idioma, la guía de Google pide una versión preferida con rel="canonical", junto con el hreflang.
  • Una traducción floja sigue floja. La anotación decide qué versión se muestra, no cuánto coincide esa versión con la consulta.
  • Las páginas espejo cuestan mantenimiento. Cada idioma es una página para construir, revisar y actualizar, y un sitio sin responsable por idioma se desincroniza.

Google describe el hreflang como una forma de informar variaciones para que el buscador las entienda. La promesa es solo esa: entender.

Donde la investigación diverge de la documentación

La primera divergencia es sobre el selector de idioma. Nielsen Norman Group recomienda detectar país e idioma por las preferencias del navegador, para que el visitante nunca abra el selector (NN/g, 6 Tips for Improving Language Switchers on Ecommerce Sites (en inglés)).

La guía de Google pide lo contrario, un enlace visible a las otras versiones (sitios multirregionales y multilingües). Advierte que la redirección automática esconde versiones del rastreador.

Las dos posiciones no son simétricas. Google lee el rastreador, que no envía cabecera Accept-Language y suele partir de Estados Unidos. NN/g lee al visitante, que es interrumpido por una elección que el navegador ya sabe.

La segunda divergencia es sobre traducción. NN/g acepta traducción por máquina con etiqueta visible y el original al lado (NN/g, Translate User-Generated Content for Global Audiences (en inglés)).

Google advierte contra traducir solo el texto genérico y mantener el cuerpo del contenido en un idioma (la misma guía). La regla de este texto queda más cerca de Google: traducción real o nada.

NN/g muestra el caso en que una traducción por máquina etiquetada vence a una sección de reseñas vacía. Ese es un camino intermedio real, y no excusa una página con el mismo slug en otro idioma.

La tercera divergencia es de alcance. NN/g encontró hablantes no nativos navegando un sitio en idioma extranjero por imágenes y diseño (NN/g, Imagery Helps International Shoppers Navigate Ecommerce Sites (en inglés)).

Eso matiza la opción de no entregar nada. Una página sin traducir con visual claro es práctica estudiada, y traducir todos los idiomas muchas veces no es viable.

Qué decidir en Astro: rutas, slug y sitemap

Tres decisiones estructurales sostienen la anotación.

  • Forma de la ruta. La guía de i18n de Astro (en inglés) coloca el contenido en carpetas [locale] dentro de src/pages/. Con prefixDefaultLocale: false, el idioma por defecto vive en la raíz y cada otro idioma lleva un prefijo.
  • Un slug por idioma. Guarda el slug en el frontmatter y nunca lo derives del título, porque editar el título movería las URLs alternativas.
  • Una fuente de verdad para el código. Deriva el valor de hreflang del prefijo de la ruta con un solo mapa. Así el atributo lang del html, el locale de Open Graph, el sitemap y la propiedad inLanguage del dato estructurado no se contradicen (schema.org, inLanguage (en inglés)).

La opción i18n (en inglés) de @astrojs/sitemap escribe el bloque xhtml:link desde el mismo mapa de locales. La integración no emite x-default, así que agrégalo en serialize cuando el sitio necesite un destino por defecto.

El build es donde todo esto se verifica. Un conteo de páginas, una revisión de alternativas y una auditoría de assets detectan los tres defectos que llegan a producción. Son la versión ausente, la alternativa huérfana y la portada que ninguna página usa.

Fuentes

Más textos

Ver todos los textos