SEO//12 min de lecture

hreflang Tags : Le guide complet d'implémentation pour le SEO multilingue

Eray Gündoğmuş
Partager

hreflang Tags : Le guide complet d'implémentation pour le SEO multilingue

Si vous gérez un site web dans plus d'une langue ou ciblez des utilisateurs dans différents pays, les hreflang tags sont le signal SEO technique le plus important que vous puissiez implémenter. Faites-le correctement et Google servira la bonne version linguistique à chaque utilisateur. Faites-le incorrectement et vous risquez des pénalités pour contenu dupliqué, une cannibalisation entre vos propres pages et une chute des rankings dans les régions que vous cherchez activement à servir.

Ce guide couvre l'ensemble du sujet : ce que font réellement les hreflang tags, les trois façons de les implémenter, chaque schéma courant que vous rencontrerez en pratique, des extraits de code spécifiques aux frameworks JavaScript modernes, les erreurs qui brisent les implémentations silencieusement, et les outils dont vous avez besoin pour tout valider avant le lancement.


TL;DR / Points clés

  • hreflang est un attribut HTML qui indique à Google quelle variante linguistique ou régionale d'une page servir pour une audience donnée. Bing n'utilise pas hreflang — il se base sur d'autres signaux comme les en-têtes HTTP Content-Language et les données de géolocalisation.
  • Chaque page d'un ensemble hreflang doit inclure une tag d'auto-référence pointant vers elle-même, en plus des tags pointant vers toutes les autres variantes.
  • Les relations hreflang doivent être bidirectionnelles : si la page A déclare la page B comme variante, la page B doit également déclarer la page A comme variante. Les déclarations unilatérales sont ignorées.
  • La valeur x-default est un désignateur de repli, pas un code de langue. Utilisez-la pour les pages qui servent de sélecteur de langues, de passerelle de redirection ou de capture pour les locales non correspondantes.
  • hreflang peut être implémenté à trois endroits : tags HTML <link> dans <head>, en-têtes de réponse HTTP ou sitemaps XML. Les trois sont également valides pour Google.

Que sont les hreflang tags ?

Les hreflang tags sont des annotations HTML qui indiquent aux moteurs de recherche quelle version d'une page est destinée aux utilisateurs parlant une langue particulière ou se trouvant dans un pays particulier. L'attribut a été introduit par Google en 2011 et est documenté dans la documentation développeur de Google Search Central sous le nom « Indiquer à Google les versions localisées de votre page ».

Le problème central que hreflang résout est la désambiguïsation. Supposons que votre site existe en anglais à /en/, en allemand à /de/ et en allemand spécifiquement pour les utilisateurs autrichiens à /de-at/. Sans hreflang, le robot d'indexation d'un moteur de recherche voit trois pages avec un contenu substantiellement similaire et doit deviner laquelle classer pour quelle audience. Il se trompe souvent. Avec hreflang, vous supprimez les suppositions et déclarez explicitement la relation.

Comment Google utilise hreflang

Lorsque Google rencontre des annotations hreflang, il les utilise pour regrouper les pages en ensembles d'équivalence. Au sein d'un ensemble, Google sélectionne la variante la plus appropriée pour chaque requête de recherche en fonction de la langue d'interface de l'utilisateur et, dans une moindre mesure, de son emplacement. La variante sélectionnée est celle qui apparaît dans les résultats de recherche pour cet utilisateur. hreflang ne garantit pas le classement — il indique seulement à Google quelle page préférer pour une audience donnée.

hreflang résout également le contenu dupliqué. Lorsque Google voit deux URLs avec un contenu identique ou quasi-identique et des liens hreflang valides les connectant, il les traite comme des variantes régionales intentionnelles plutôt que des doublons accidentels.

Google vs Bing : Une distinction importante

hreflang est une fonctionnalité de Google (et Yandex). Bing n'utilise explicitement pas les hreflang tags. Selon les Directives pour les webmasters de Bing, Bing utilise les signaux suivants pour déterminer la langue et la région cible d'une page :

  • L'en-tête de réponse HTTP Content-Language
  • L'attribut lang sur l'élément <html>
  • L'emplacement géographique du serveur
  • Le domaine de premier niveau avec code pays (ccTLD), le cas échéant
  • Le contenu de la page elle-même

Si Bing est une source de trafic significative pour vos audiences internationales, vous devez implémenter ces signaux indépendamment de votre configuration hreflang. Un site multilingue bien construit implémente généralement les deux : hreflang pour Google et l'attribut lang sur <html> plus les en-têtes Content-Language pour Bing. Les deux approches ne sont pas en conflit.


Syntaxe et placement

Format des codes de langues et de régions

Les valeurs hreflang suivent le format défini par IETF BCP 47. En pratique, cela signifie :

  • Langue uniquement : en, de, fr, ja, zh-Hans, zh-Hant
  • Langue plus région : en-US, en-GB, de-AT, fr-CA, pt-BR
  • Valeur spéciale : x-default

Les codes de langues sont des codes à deux lettres ISO 639-1. Les codes de régions sont des codes à deux lettres ISO 3166-1 alpha-2. Le séparateur est un tiret, pas un underscore. Une erreur courante est d'écrire en_US (underscore) au lieu de en-US (tiret) — Google ignore complètement la variante avec underscore.

C'est la méthode la plus utilisée. Placez des éléments <link> dans le <head> de chaque page de l'ensemble hreflang.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Product Page</title>

  <!-- Tag d'auto-référence (obligatoire) -->
  <link rel="alternate" hreflang="en" href="https://example.com/en/product/" />

  <!-- Autres variantes linguistiques -->
  <link rel="alternate" hreflang="de" href="https://example.com/de/product/" />
  <link rel="alternate" hreflang="fr" href="https://example.com/fr/product/" />
  <link rel="alternate" hreflang="de-AT" href="https://example.com/de-at/product/" />

  <!-- Repli pour les locales non correspondantes -->
  <link rel="alternate" hreflang="x-default" href="https://example.com/product/" />
</head>
<body>
  <!-- contenu de la page -->
</body>
</html>

Chaque variante linguistique de cette page doit inclure exactement le même ensemble de tags <link>. La page allemande à /de/product/ doit également avoir les cinq éléments <link>, y compris celui pointant vers /en/product/.

Méthode 2 : En-têtes de réponse HTTP

Pour les ressources non HTML — les PDFs étant le cas le plus courant — vous ne pouvez pas incorporer de tags HTML. Le serveur web émet hreflang comme partie de l'en-tête de réponse HTTP Link.

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Link: <https://example.com/en/product/>; rel="alternate"; hreflang="en",
      <https://example.com/de/product/>; rel="alternate"; hreflang="de",
      <https://example.com/fr/product/>; rel="alternate"; hreflang="fr",
      <https://example.com/product/>; rel="alternate"; hreflang="x-default"

Dans une configuration Nginx :

location /en/product/ {
    add_header Link '<https://example.com/en/product/>; rel="alternate"; hreflang="en", <https://example.com/de/product/>; rel="alternate"; hreflang="de", <https://example.com/fr/product/>; rel="alternate"; hreflang="fr"';
}

Les en-têtes HTTP sont analysés avant le corps HTML, ce qui les rend légèrement plus efficaces pour les robots d'indexation, mais la différence de classement pratique est négligeable.

Méthode 3 : Sitemap XML

Pour les grands sites avec des milliers d'URLs, maintenir des hreflang tags sur chaque page individuelle est coûteux opérationnellement. Les sitemaps XML offrent une alternative centralisée via l'élément xhtml:link.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">

  <!-- Variante anglaise -->
  <url>
    <loc>https://example.com/en/product/</loc>
    <xhtml:link rel="alternate" hreflang="en"       href="https://example.com/en/product/" />
    <xhtml:link rel="alternate" hreflang="de"       href="https://example.com/de/product/" />
    <xhtml:link rel="alternate" hreflang="fr"       href="https://example.com/fr/product/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/product/" />
  </url>

  <!-- Variante allemande — même ensemble d'éléments xhtml:link -->
  <url>
    <loc>https://example.com/de/product/</loc>
    <xhtml:link rel="alternate" hreflang="en"       href="https://example.com/en/product/" />
    <xhtml:link rel="alternate" hreflang="de"       href="https://example.com/de/product/" />
    <xhtml:link rel="alternate" hreflang="fr"       href="https://example.com/fr/product/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/product/" />
  </url>

  <!-- Variante française — même ensemble d'éléments xhtml:link -->
  <url>
    <loc>https://example.com/fr/product/</loc>
    <xhtml:link rel="alternate" hreflang="en"       href="https://example.com/en/product/" />
    <xhtml:link rel="alternate" hreflang="de"       href="https://example.com/de/product/" />
    <xhtml:link rel="alternate" hreflang="fr"       href="https://example.com/fr/product/" />
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/product/" />
  </url>

</urlset>

Schémas hreflang courants

Même langue, régions différentes

Utilisez des tags langue-plus-région lorsque vous avez un contenu significativement différent pour la même langue dans différents pays — prix différents, textes juridiques différents, disponibilité des produits différente.

<!-- Anglais des États-Unis -->
<link rel="alternate" hreflang="en-US" href="https://example.com/us/checkout/" />

<!-- Anglais du Royaume-Uni -->
<link rel="alternate" hreflang="en-GB" href="https://example.com/uk/checkout/" />

<!-- Anglais d'Australie -->
<link rel="alternate" hreflang="en-AU" href="https://example.com/au/checkout/" />

<!-- Repli pour tous les autres anglophones -->
<link rel="alternate" hreflang="en" href="https://example.com/en/checkout/" />

Si les différences sont triviales (un symbole monétaire ou un format de numéro de téléphone), le coût de maintenance d'URLs séparées peut ne pas justifier l'avantage SEO.

La tag x-default

x-default désigne la page que Google doit montrer aux utilisateurs dont la langue ne correspond à aucune de vos variantes déclarées.

<!-- Variantes linguistiques spécifiques -->
<link rel="alternate" hreflang="en" href="https://example.com/en/" />
<link rel="alternate" hreflang="de" href="https://example.com/de/" />
<link rel="alternate" hreflang="ja" href="https://example.com/ja/" />

<!-- x-default : affiché quand aucune variante ne correspond à la langue de l'utilisateur -->
<link rel="alternate" hreflang="x-default" href="https://example.com/" />

x-default n'est pas un code de langue. Ne l'utilisez pas comme synonyme d'anglais.

Exigence d'auto-référence

Chaque page d'un ensemble hreflang doit inclure une tag pointant vers elle-même. Ce n'est pas optionnel. La documentation de Google le précise explicitement.

<!-- Sur la page /de/, l'auto-référence est la tag hreflang="de" -->
<link rel="alternate" hreflang="de" href="https://example.com/de/about/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/about/" />

Exigence de liens retour (bidirectionnalité)

Si la page A déclare la page B comme alternative, la page B doit déclarer la page A comme alternative. C'est l'échec silencieux le plus courant dans les implémentations hreflang.


Implémentation dans les frameworks populaires

Next.js (App Router)

Dans le App Router de Next.js, utilisez la propriété alternates dans la fonction generateMetadata.

// app/[locale]/product/[slug]/page.tsx
import type { Metadata } from 'next';

type Props = {
  params: { locale: string; slug: string };
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { locale, slug } = params;
  const baseUrl = 'https://example.com';

  return {
    alternates: {
      canonical: `${baseUrl}/${locale}/product/${slug}/`,
      languages: {
        'en': `${baseUrl}/en/product/${slug}/`,
        'de': `${baseUrl}/de/product/${slug}/`,
        'fr': `${baseUrl}/fr/product/${slug}/`,
        'x-default': `${baseUrl}/en/product/${slug}/`,
      },
    },
  };
}

Nuxt 3

Le module @nuxtjs/i18n de Nuxt génère automatiquement les hreflang tags lorsque seo: true est configuré. Pour un contrôle manuel, utilisez le composable useHead.

// composables/useHreflang.ts
export function useHreflang(slug: string) {
  const baseUrl = 'https://example.com';
  const locales = ['en', 'de', 'fr'];

  useHead({
    link: [
      ...locales.map((locale) => ({
        rel: 'alternate' as const,
        hreflang: locale,
        href: `${baseUrl}/${locale}/${slug}/`,
      })),
      {
        rel: 'alternate' as const,
        hreflang: 'x-default',
        href: `${baseUrl}/en/${slug}/`,
      },
    ],
  });
}

Astro

Le getStaticPaths d'Astro facilite la construction de l'ensemble complet de variantes pour chaque page.

---
// src/layouts/BaseLayout.astro
interface Props {
  hreflangLinks: Array<{ hreflang: string; href: string }>;
}
const { hreflangLinks } = Astro.props;
---
<html>
  <head>
    {hreflangLinks.map((link) => (
      <link rel="alternate" hreflang={link.hreflang} href={link.href} />
    ))}
  </head>
  <body>
    <slot />
  </body>
</html>
---
// src/pages/[locale]/[slug].astro
export async function getStaticPaths() {
  const baseUrl = 'https://example.com';
  const locales = ['en', 'de', 'fr'];
  const slugs = ['about', 'pricing', 'contact'];

  return locales.flatMap((locale) =>
    slugs.map((slug) => ({
      params: { locale, slug },
      props: {
        hreflangLinks: [
          ...locales.map((l) => ({
            hreflang: l,
            href: `${baseUrl}/${l}/${slug}/`,
          })),
          { hreflang: 'x-default', href: `${baseUrl}/en/${slug}/` },
        ],
      },
    }))
  );
}
const { hreflangLinks } = Astro.props;
---
<BaseLayout hreflangLinks={hreflangLinks}>
  <!-- contenu de la page -->
</BaseLayout>

TanStack Start

TanStack Start utilise le routage basé sur les fichiers avec createFileRoute. Injectez les hreflang tags en utilisant l'export head d'un fichier de route.

// routes/$locale.product.$slug.tsx
import { createFileRoute } from '@tanstack/start';

const locales = ['en', 'de', 'fr'] as const;
const baseUrl = 'https://example.com';

export const Route = createFileRoute('/$locale/product/$slug')({
  head: ({ params }) => {
    const { locale, slug } = params;

    const hreflangLinks = [
      ...locales.map((l) => ({
        tag: 'link' as const,
        attrs: {
          rel: 'alternate',
          hreflang: l,
          href: `${baseUrl}/${l}/product/${slug}/`,
        },
      })),
      {
        tag: 'link' as const,
        attrs: {
          rel: 'alternate',
          hreflang: 'x-default',
          href: `${baseUrl}/en/product/${slug}/`,
        },
      },
    ];

    return { links: hreflangLinks };
  },
  component: ProductPage,
});

function ProductPage() {
  const { locale, slug } = Route.useParams();
  return <div>{/* contenu de la page */}</div>;
}

Les frameworks avec routage i18n intégré, comme Next.js avec @formatjs/intl ou des plateformes comme Better i18n qui gèrent la livraison des traductions, peuvent générer ou automatiser l'output hreflang au build ou à l'exécution.


Erreurs courantes

Auto-référence manquante

Chaque page doit se déclarer elle-même. L'auto-référence doit utiliser exactement la même URL que la valeur <loc> dans votre sitemap.

<!-- INCORRECT : la page /de/ ne se référence pas elle-même -->
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/about/" />

<!-- CORRECT : la page /de/ inclut sa propre auto-référence -->
<link rel="alternate" hreflang="de" href="https://example.com/de/about/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/about/" />

Liens retour manquants

Lorsque vous ajoutez une nouvelle variante linguistique, vous devez mettre à jour chaque page existante dans l'ensemble pour inclure un lien vers la nouvelle variante.

Codes de langues incorrects

Erreurs courantes :

  • en_US au lieu de en-US (underscore vs tiret)
  • zh quand on veut dire zh-Hans (Simplifié) ou zh-Hant (Traditionnel)
  • pt quand il faut distinguer pt-PT (Portugal) de pt-BR (Brésil)
  • Codes ISO 639-2 à trois lettres (zho, deu) au lieu de codes ISO 639-1 à deux lettres (zh, de)

Mélanger hreflang avec des canonical tags incorrectes

La canonical tag et l'auto-référence hreflang doivent pointer vers la même URL.

<!-- INCORRECT : canonical et auto-référence hreflang ne concordent pas -->
<link rel="canonical" href="https://example.com/product/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/product/" />

<!-- CORRECT : canonical et auto-référence pointent vers la même URL -->
<link rel="canonical" href="https://example.com/en/product/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/product/" />

Utiliser hreflang pour des pages non équivalentes

hreflang déclare que deux pages sont des traductions ou des variantes régionales l'une de l'autre. L'utiliser pour connecter des pages qui ne sont pas réellement équivalentes fait mal interpréter la structure du site par Google.


Outils de validation

Google Search Console

Le rapport de Couverture dans Google Search Console affiche directement les erreurs hreflang. Types d'erreurs courants :

  • Alternate page with proper canonical tag : Comportement correct, pas une vraie erreur malgré l'intitulé.
  • Return tag missing : Google a trouvé un lien hreflang mais la page cible ne renvoie pas de lien. Ajoutez la return tag manquante.
  • No hreflang tag : Une page est référencée comme alternative mais ne contient pas de hreflang tags.

Outils de vérification hreflang

  • hreflang.org Tag Checker : Collez une URL pour voir toutes les annotations hreflang trouvées et si des return links existent.
  • Outil de test hreflang d'Aleyda Solis : Outil gratuit, utile pour vérifier des URLs individuelles.
  • Générateur de hreflang Tags de Merkle : Génère du markup HTML, d'en-tête HTTP ou de sitemap syntaxiquement correct.

Screaming Frog SEO Spider

Pour les audits à grande échelle, Screaming Frog crawle l'ensemble du site et signale les return links manquants, les codes de langues invalides et les canonicals non concordants.


FAQ

hreflang affecte-t-il directement les classements ?

Non. hreflang prévient les problèmes de contenu dupliqué et garantit que la bonne page concourt pour la bonne audience, ce qui peut améliorer indirectement les taux de clics et les signaux d'engagement.

Puis-je utiliser hreflang sur un site en une seule langue mais avec plusieurs versions par pays ?

Oui. Si vous avez des pages distinctes pour les anglophones aux États-Unis, au Royaume-Uni et en Australie avec un contenu genuinement différent, l'utilisation des tags en-US, en-GB et en-AU est correcte.

Combien de temps faut-il à Google pour traiter les changements hreflang ?

Pour la plupart des sites, cela prend des jours à des semaines. Soumettre un sitemap XML mis à jour via Search Console accélère le processus.

Dois-je utiliser hreflang sur chaque page ou seulement sur les pages clés ?

Sur chaque page qui a une variante traduite. Une implémentation partielle cause des incohérences imprévisibles.

Que se passe-t-il si j'ai des erreurs hreflang et que je ne fais rien ?

Google traite les annotations erronées comme si elles n'existaient pas et revient à ses propres signaux. En général, la mauvaise variante régionale apparaît dans les résultats de recherche.


Conclusion

Les hreflang tags sont l'une des exigences SEO les plus techniquement exigeantes pour les sites internationaux, non pas parce que la tag individuelle est compliquée, mais parce que l'implémentation doit être cohérente sur chaque page, chaque variante et chaque méthode choisie. Un seul return link cassé ou une auto-référence manquante peut silencieusement invalider une partie du ciblage international.

La liste de contrôle pratique : codes BCP 47 avec tirets, toujours une auto-référence, toujours des liens bidirectionnels, aligner les canonical tags avec les auto-références hreflang, valider avec Screaming Frog et Search Console avant le lancement.

Pour les nouveaux projets, le chemin de moindre résistance est de choisir un framework ou une plateforme qui génère automatiquement l'output hreflang dans le cadre de son routage i18n. Pour les sites existants, une implémentation de sitemap XML est généralement la mise à niveau la moins coûteuse.


Références

Comments

Loading comments...