Un client m'appelle un jour, paniqué. Son site vient d'ouvrir une version canadienne-française. Deux semaines plus tard, dans Search Console, la page /fr-ca/prix s'affiche à la place de /fr-fr/tarifs pour des internautes à Lyon. Il me demande si Google « s'est trompé ». Non. C'est lui qui n'avait rien dit à Google.
La balise hreflang sert exactement à ça : préciser à quel public linguistique et géographique s'adresse chaque URL d'un site multilingue. Sans elle, le moteur devine. Et quand il devine, il se trompe souvent. Je l'ai vérifié une bonne dizaine de fois sur des projets clients : la version qui remonte dans les résultats n'est presque jamais celle qu'on attendait.
Points clés à retenir
- La balise hreflang déclare la langue et éventuellement la région d'une URL, jamais son contenu
- Chaque page doit se référencer elle-même, sinon la grappe de signaux est ignorée
- Les liens doivent être réciproques : A pointe vers B, B pointe vers A
x-defaultdésigne la page de secours pour les langues non couvertes- hreflang et canonical ne s'opposent pas, ils se complètent
- Un hreflang cassé ne pénalise pas, il fait juste ignorer tout le bloc concerné
Comprendre hreflang avant de la poser
Une hreflang n'est pas une redirection. Elle ne force personne à aller nulle part. C'est une indication passive, lue par les robots d'exploration, qui dit : « cette URL est la variante française pour la France, celle-là est la variante française pour la Belgique ».
Anatomie d'une balise
Le format est <link rel="alternate" hreflang="xx-YY" href="URL" />. Le xx suit la norme ISO 639-1 pour la langue (fr, en, es, de…). Le YY suit ISO 3166-1 alpha-2 pour la région (FR, CA, BE, CH…). La région est optionnelle. Si vous mettez juste fr, vous visez tous les locuteurs francophones sans distinction géographique.
Attention à un piège que je vois tout le temps : fr-CA désigne le français parlé au Canada, pas le Canada. en-CA, c'est de l'anglais canadien. Si vous voulez cibler un public anglophone au Canada sans préciser la langue, ce n'est pas fr-CA qu'il faut écrire.
Où placer la balise
Trois emplacements possibles : dans le <head> de chaque page HTML, dans un sitemap XML, ou via un en-tête HTTP Link pour les fichiers non-HTML (PDF, par exemple). Le plus courant reste le <head>. Je recommande le sitemap XML pour les gros sites, c'est plus simple à maintenir et à auditer.
Un exemple de code complet, à copier
Voici le bloc que je pose systématiquement dans le <head> d'une page française ciblant la France, avec une variante canadienne et une version anglaise :
<link rel="alternate" hreflang="fr-fr" href="https://exemple.com/fr-fr/tarifs" />
<link rel="alternate" hreflang="fr-ca" href="https://exemple.com/fr-ca/prix" />
<link rel="alternate" hreflang="en" href="https://exemple.com/en/pricing" />
<link rel="alternate" hreflang="x-default" href="https://exemple.com/en/pricing" /> Trois choses à remarquer. D'abord, la première ligne référence la page elle-même. C'est ce qu'on appelle l'auto-référence, et sans elle la grappe entière est ignorée. Ensuite, la ligne en sans région cible tous les anglophones. Enfin, x-default pointe vers la page de secours, celle qu'on sert à un internaute dont la langue n'est couverte nulle part.
Pourquoi x-default est presque toujours oubliée
Je pourrais écrire un mémoire sur le nombre de sites qui n'ont pas de x-default. C'est la ligne qu'on oublie, celle qu'on croit facultative. Elle ne l'est pas vraiment. Si quelqu'un au Japon tombe sur votre site et qu'aucune version ne correspond à sa langue, c'est la page indiquée par x-default qui s'affichera. Sans elle, Google choisit tout seul. Et il choisit rarement bien.
Que faire quand une traduction n'existe pas ?
C'est la question qu'on me pose le plus en audit. Vous avez une page en français, en anglais, et en allemand, mais pas en italien. Que déclarer ?
La règle est simple : une page absente ne doit pas apparaître dans la grappe hreflang. Vous n'écrivez pas it en espérant que Google devine. Vous ne mettez it que si l'URL italienne existe. Si vous mettez un hreflang vers une URL en 404, vous cassez toute la grappe pour cette langue, et Google finit par ignorer le bloc entier.
Si vous finissez par créer la version italienne, vous mettez à jour toutes les pages de la grappe pour ajouter la ligne correspondante. Et vous ajoutez la nouvelle page à l'auto-référence.
- Page française : ajouter
itdans son<head> - Page anglaise : même opération
- Page allemande : idem
- Nouvelle page italienne : elle référence les trois autres et se référence elle-même
Ouais, c'est fastidieux. C'est pour ça que sur les sites à plus de 20 langues, je bascule tout dans le sitemap XML et je génère le fichier dynamiquement.
hreflang, canonical et sitemap : qui fait quoi
On m'a déjà demandé si mettre un canonical vers la version anglaise « annulait » l'effet du hreflang. Non. Les deux balises ont des rôles distincts, et elles cohabitent très bien.
| Balise | Rôle | Cible |
|---|---|---|
| hreflang | Indiquer la variante linguistique / régionale | Une URL équivalente dans une autre langue |
| canonical | Désigner la page de référence en cas de duplication | Une seule URL, celle qu'on veut voir indexée |
| sitemap XML | Lister les URLs à explorer, avec leurs hreflang | Toutes les variantes d'un coup |
Un cas concret : vous avez une page /fr/tarifs et une /fr/tarifs?utm=newsletter. La deuxième est une duplication. Le canonical pointe vers la première. Le hreflang, lui, continue de pointer vers les versions anglaise, allemande, etc. Aucun conflit.
Le piège du canonical mal placé
Le vrai problème arrive quand on met un canonical qui pointe vers une autre langue. J'ai vu un site dont la version française pointait en canonical vers la version anglaise, sous prétexte que « l'anglais est la version principale ». Résultat : la page française disparaissait des résultats français. C'était une erreur de conception, pas de balise.
Les erreurs qui tuent une grappe hreflang
Il y a cinq erreurs que je retrouve systématiquement. Elles sont toutes silencieuses : rien ne plante, rien ne casse dans le navigateur. Google se contente d'ignorer la grappe.
- Absence d'auto-référence — la page qui déclare les autres langues mais oublie de se déclarer elle-même.
- Liens non réciproques — A pointe vers B, mais B ne pointe pas vers A. Google exige la réciprocité.
- Codes de langue inventés —
fr-FRest correct,FR-fraussi dans certains cas maisfrenchoufr_FRavec underscore ne passent pas. - URL en relatif —
href="/fr/tarifs"au lieu de l'URL absolue complète. Google veut l'URL entière. - Hreflang vers une page redirigée — la cible renvoie un 301. La grappe est cassée.
Le point numéro 2 est le plus vicieux. Sur un site WordPress mal configuré, les plugins génèrent le hreflang de manière automatique, mais oublient parfois une page dans une langue. Vous avez 12 pages en français, 11 en anglais. La douzième page française pointe vers une URL anglaise qui n'existe pas.
Comment auditer ses balises sans se noyer
La méthode que j'utilise : ouvrir la page dans le navigateur, faire un clic droit, « afficher le code source », et chercher hreflang. S'il y en a quatre, vous vérifiez les quatre. S'il y en a trente, vous ouvrez un outil.
En ligne de commande, c'est immédiat :
curl -s https://exemple.com/fr-fr/tarifs | grep hreflang Pour un audit complet, je passe par des outils dédiés qui crawlent tout le site et remontent les erreurs. Mais franchement, pour un site à moins de 50 pages, un tableur avec deux colonnes (URL source, URL cible déclarée) suffit. Vous vérifiez que chaque cible existe, qu'elle est bien en 200, et qu'elle référence en retour la page source.
Faut-il tout automatiser ?
Les CMS comme WordPress ou Shopify génèrent les balises hreflang automatiquement, en général via des extensions multilingues. C'est pratique et ça évite les oublis. Mais ça n'empêche pas les erreurs de configuration. J'ai vu un site Shopify où le hreflang était bien généré, mais où deux marchés pointaient vers la même URL. L'extension avait mal interprété la configuration. Personne ne s'en était aperçu pendant huit mois.
Mon avis, et là je suis catégorique : automatisez la génération, mais auditez manuellement une fois par trimestre. La configuration change, les marchés évoluent, et ce qui marchait il y a six mois peut être cassé aujourd'hui.
Ce qu'il faut vraiment retenir
La balise hreflang n'est pas magique. C'est un signal parmi d'autres, et Google reste maître de la décision finale. Je l'ai constaté sur un projet à 8 langues : malgré un hreflang impeccable, certaines requêtes remontaient la mauvaise version pendant des semaines, avant que Google ne se stabilise.
Ce qui compte, au fond, c'est la cohérence. Une grappe complète, réciproque, avec auto-référence et x-default. Et un canonical qui ne vient pas contredire le tout. Le reste, Google s'en charge.
Si vous devez ne retenir qu'une seule chose de cet article, ce serait celle-ci : chaque page qui parle d'une variante doit aussi parler d'elle-même. C'est bête. C'est banal. Et c'est l'erreur que je corrige le plus souvent.