AldeaCode Logo
SEO Hreflang y canonical: guía con ejemplos de código
SEO AldeaCode Architecture

Hreflang y canonical: guía con ejemplos de código

Cómo funcionan hreflang y canonical juntos para SEO internacional. Ejemplos de código, reglas de reciprocidad y errores que rompen el posicionamiento.

El problema en lenguaje claro

Publicas un artículo en inglés en /blog/post. Lo traduces al español y lo publicas en /es/blog/post. La misma idea, en otro idioma. Para ti son dos páginas que sirven a dos audiencias. Para Google son dos URLs con estructura muy parecida, imágenes parecidas, enlaces internos parecidos y el mismo autor.

Sin una señal clara por tu parte, Google tiene que adivinar. A veces elige una y se la muestra a todo el mundo. A veces las junta como duplicados. A veces le sirve la versión en español a un lector en Nueva York. Nada de eso es lo que querías.

El hreflang es esa señal. Le dice a los buscadores en qué idioma está cada página, y qué otras URLs son la versión equivalente en otros idiomas. Combinado con un canonical limpio, evita que las dos páginas compitan entre sí y deja que cada una posicione frente al público adecuado.

Es el mismo tipo de claridad estructural que aplicas en una jerarquía semántica sólida: dejas la estructura obvia para que el rastreador no tenga que inventarse el significado.

Qué dice realmente el hreflang

Una etiqueta hreflang es una declaración pequeña. En el head de una página HTML se ve así.

<link rel="alternate" hreflang="en" href="https://aldeacode.com/blog/post" />
<link rel="alternate" hreflang="es" href="https://aldeacode.com/es/blog/post" />
<link rel="alternate" hreflang="x-default" href="https://aldeacode.com/blog/post" />

En lenguaje claro, esas líneas dicen: “la versión en inglés de este contenido está en la primera URL, la versión en español está en la segunda, y si el idioma del visitante no coincide con ninguna, mándalo a la URL por defecto”.

Pones el mismo bloque en las dos páginas. La página en inglés declara su URL en inglés y su URL en español. La página en español declara su URL en inglés y su URL en español. Ambas páginas referencian ambas URLs. Esa parte no es opcional, y es la parte que más gente equivoca.

La regla de la reciprocidad

Toda relación hreflang tiene que ser mutua. Si la página A dice “mi versión en español es la página B”, la página B tiene que decir “mi versión en inglés es la página A”. Si solo un lado declara la relación, Google ignora ambas declaraciones.

Por eso una migración a medias rompe todo. Añades hreflang a las páginas nuevas, te olvidas de añadirlo a las viejas, y el resultado es que ninguna de tus señales hreflang cuenta. Las páginas siguen compitiendo entre sí.

Una comprobación práctica: antes de subir hreflang a producción, lista cada par de URLs en una hoja de cálculo. Para cada par, confirma que ambas URLs declaran ambas alternativas y que ambas se declaran a sí mismas. Tres líneas por página, en cada página del set. Si la hoja está incompleta, la implementación está incompleta.

La autorreferencia importa

Cada página tiene que incluir un enlace hreflang que apunte a sí misma. La página en inglés lista su propia URL en inglés. La página en español lista su propia URL en español. Eso es lo que le dice a Google “esta es la versión en inglés, no solo una página que casualmente conoce una versión en inglés”.

Saltarse la autorreferencia es un fallo silencioso. Search Console no siempre lo grita, pero la señal queda incompleta y Google puede no actuar sobre ella.

El valor x-default

x-default es un fallback. No significa “inglés”. Significa “cualquier visitante cuya preferencia de idioma no coincida con ninguna de las otras declaraciones”.

El sitio más útil para x-default es la portada de un sitio multilingüe. Un visitante llega a la raíz, su navegador está en polaco, no tienes versión en polaco: ¿adónde va? x-default responde a esa pregunta. Lo apuntas a la URL que quieres que vea cuando ninguna de las opciones explícitas encaja.

En páginas profundas con dos o tres versiones de idioma, x-default es menos crítico. En páginas de primer nivel de un sitio que apunta a muchas regiones, es parte del kit básico.

Códigos de idioma, hechos bien

Hreflang usa códigos ISO. Dos letras para idioma (en, es, fr, de), y un código de región opcional de dos letras tras un guion (en-US, en-GB, es-ES, es-MX).

Errores comunes:

  • Inventar códigos. No existe uk para inglés británico. El código es en-GB. No existe cn para chino. Los códigos son zh-Hans para simplificado y zh-Hant para tradicional.
  • Usar solo el idioma cuando el contenido es regional. Si tu página en inglés muestra precios en dólares y envía desde un almacén en EE. UU., eso es en-US, no en. Un lector en Manchester ve precios en dólares y se va.
  • Usar solo la región. en-GB funciona. GB solo no. El idioma siempre va primero.
  • Mezclar mayúsculas y minúsculas. La convención es idioma en minúscula y región en mayúscula: en-GB, no en-gb ni EN-GB. Los buscadores toleran variaciones, pero la consistencia hace mucho más fácil auditar la implementación.

Si tu sitio es una sola versión global en inglés sin diferencias regionales, en está bien. Si tienes versiones distintas para EE. UU. y Reino Unido con copy, precios o stock diferentes, usa los códigos regionales y sirve contenido distinto. Las medias tintas aquí son peores que no poner hreflang.

Canonical junto a hreflang

Aquí es donde más equipos tropiezan. La etiqueta canonical es por idioma. La página en inglés es su propio canonical. La página en español es su propio canonical.

<!-- en /blog/post -->
<link rel="canonical" href="https://aldeacode.com/blog/post" />

<!-- en /es/blog/post -->
<link rel="canonical" href="https://aldeacode.com/es/blog/post" />

Un error frecuente es poner la URL en inglés como canonical de la página en español, pensando que así se consolida la señal del “duplicado”. Hace lo contrario. Decirle a Google que tu página en español tiene como canonical la inglesa es decirle que no indexe la página en español. El hreflang y el canonical se contradicen, y Google resuelve la contradicción siguiendo el canonical.

La regla limpia: cada versión de idioma es su propio canonical, y el hreflang declara las relaciones entre ellas. El canonical maneja duplicación dentro del mismo idioma (una página accesible por dos rutas, una versión imprimible, una URL con parámetros de tracking). El hreflang maneja la equivalencia entre idiomas.

¿Etiquetas o sitemap?

Puedes declarar hreflang de dos formas: con etiquetas <link> por página en el head HTML, o con entradas <xhtml:link> dentro de cada bloque <url> del sitemap.

La opción a nivel de página está bien para sitios pequeños. Dos idiomas, cincuenta páginas, lo puedes mantener consistente. La opción del sitemap es mucho más fácil de mantener a escala. Un solo archivo, un único sitio donde actualizar, sin riesgo de olvidar una etiqueta en una página que rompe la reciprocidad de todo un par.

Una entrada mínima de sitemap para un par hreflang se ve así.

<url>
  <loc>https://aldeacode.com/blog/post</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://aldeacode.com/blog/post" />
  <xhtml:link rel="alternate" hreflang="es" href="https://aldeacode.com/es/blog/post" />
</url>
<url>
  <loc>https://aldeacode.com/es/blog/post</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://aldeacode.com/blog/post" />
  <xhtml:link rel="alternate" hreflang="es" href="https://aldeacode.com/es/blog/post" />
</url>

Aplican las mismas reglas de reciprocidad. Las dos URLs listan las dos alternativas.

Cómo verificar la implementación

Google Search Console es el sitio canónico para comprobarlo. Hay dos herramientas que importan.

La primera es la herramienta de inspección de URLs. Pegas una URL, despliegas la sección de “Indexación de la página” y Google te dice qué hreflang ha recogido y si las alternativas son válidas.

La segunda fue históricamente el informe de Segmentación Internacional. Google ha reorganizado esa interfaz varias veces, así que el nombre exacto del menú puede cambiar cuando leas esto. La señal que buscas es el error “no return tags” (sin etiquetas de retorno). Ese error significa que la página A declaró la página B como alternativa, pero la página B no declaró la página A de vuelta. La reciprocidad está rota en ese par, y la corrección está en la página que no devolvió la etiqueta.

Vuelve a comprobar después de cada deploy que toque plantillas, selectores de idioma o generación de sitemap. El patrón de bug casi siempre es “actualizamos un lado y olvidamos el otro”.

Errores comunes a evitar

  • Banderas de país como indicador de idioma. Una bandera es un país, no un idioma. Un lector en Ciudad de México no se siente atendido por una bandera de España. Un lector en Quebec no se siente atendido por una bandera de Francia. Usa el nombre del idioma en su propio idioma: “Español”, “Français”, “English”. Las banderas son decoración en el mejor de los casos, y alienan en el peor.
  • Usar solo códigos de idioma para contenido regional. Si tus precios, opciones de envío o textos legales cambian por región, el código de región es parte del significado. en-US y en-GB son versiones distintas, no duplicados.
  • Olvidar x-default en la portada. Cualquier visitante cuyo idioma no esté en tu set tiene que aterrizar en algún sitio. Decide cuál, declárelo y deja de adivinar.
  • Mezclar canonical y hreflang. Cada idioma es su propio canonical. El hreflang es el puente entre idiomas. Hacen trabajos distintos. Nunca deben contradecirse.
  • Migraciones a medias. Añadir hreflang a la mitad de un sitio es peor que no añadirlo. La reciprocidad tiene que ser completa o Google la ignora.

El mismo cuidado que pones en las Core Web Vitals o en un presupuesto de rendimiento ajustado toca aquí. El SEO internacional no es trabajo glamuroso. Son declaraciones pequeñas en cada página, mantenidas con consistencia en el tiempo. Bien hecho, dejas de competir contigo mismo en los resultados.

Preguntas frecuentes

¿Necesito hreflang si mi sitio está en un solo idioma? No. El hreflang solo importa cuando tienes dos o más versiones de idioma o región del mismo contenido. Un sitio monolingüe usa solo canonical.

¿Qué diferencia hay entre hreflang y el atributo lang? El atributo lang en el elemento <html> le dice al navegador y a las tecnologías de asistencia en qué idioma está la página actual. El hreflang le dice a los buscadores qué otras versiones de idioma existen del mismo contenido. Sirven a públicos distintos. Pon los dos.

¿Puedo usar hreflang para contenido que no es traducción? El hreflang es para el mismo contenido en idiomas o regiones distintas. Si dos páginas apuntan a audiencias distintas con contenido distinto, no son alternativas hreflang. Son páginas distintas.

¿Cuánto tarda Google en aplicar cambios de hreflang? Días o semanas. Search Console recoge las etiquetas nuevas en el siguiente rastreo, pero el efecto sobre qué versión posiciona dónde tarda más. No te pongas nervioso al tercer día.

¿Y si mis traducciones son parciales? Declara hreflang solo para URLs que existan y sean realmente equivalentes. Declarar una URL que devuelve 404 o que tiene contenido muy distinto te perjudica. Despliega hreflang a medida que las traducciones aterrizan.

Lo que hacemos

Webs honestas, sin atajos.

Ingeniería real y diseño cuidado. Si te ha gustado el post, hablemos del tuyo.

Hablemos →

Te puede interesar

Ver todos los artículos →