Apprendre
Hreflang Tags: Syntax, Common Errors and How to Validate Them
Hreflang is not a ranking signal — it tells Google which language version to show which user. Almost every broken implementation fails the same rule: the links must point both ways.
Lancez un audit DomainLens frais et utilisez le rapport comme liste de priorités.
What hreflang does, and what it does not
Hreflang tells Google that several URLs are the same content in different languages or for different regions, and which one suits which audience. Google then swaps in the appropriate version for each searcher instead of showing them all or picking arbitrarily.
It does not consolidate ranking signals — that is what canonical does — and it does not make a page rank in a country. A Spanish page still has to earn its position; hreflang only makes sure the Spanish speaker is shown the Spanish one rather than the English original.
The syntax, and the three places it can live
Annotations can go in the HTML head, in HTTP headers, or in the XML sitemap. Pick one and use it consistently — mixing methods makes conflicts almost impossible to trace.
- Use ISO 639-1 for language and, optionally, ISO 3166-1 Alpha 2 for region: en, de, en-gb, pt-br.
- Region alone is invalid. hreflang="uk" means Ukrainian, not the United Kingdom — that is en-gb.
- URLs must be absolute, including the scheme.
- x-default names the fallback for users no other entry matches.
<!-- In the head of every version, including itself -->
<link rel="alternate" hreflang="en" href="https://example.com/page">
<link rel="alternate" hreflang="de" href="https://example.com/de/page">
<link rel="alternate" hreflang="x-default" href="https://example.com/page">
<!-- As an HTTP header, for non-HTML files such as PDFs -->
Link: <https://example.com/de/page>; rel="alternate"; hreflang="de"
<!-- In the sitemap, as xhtml:link on each url entry -->
<url>
<loc>https://example.com/page</loc>
<xhtml:link rel="alternate" hreflang="de" href="https://example.com/de/page"/>
</url>
The reciprocity rule that breaks most implementations
Every page in a set must list every page in the set, including itself. If the English page links to the German one but the German page does not link back, Google discards the annotation entirely — not partially, entirely.
This is why hreflang usually fails at scale rather than on a single page: the set is generated per page from a partial list, so each page names a slightly different group and none of them agree.
| Error | What Google does | Fix |
|---|---|---|
| No return link | Ignores the annotation | Generate the set from one shared list |
| Wrong language code | Ignores that entry | Use ISO 639-1, not a country name |
| Relative URLs | Cannot resolve them | Always absolute |
| Points at a redirect | Discards the entry | Link the final URL |
| Alternate is noindexed | Cannot serve it | Remove noindex or drop the entry |
| Missing self-reference | Set is incomplete | Include the page itself |
How to validate an implementation
- 1Fetch a page and read the alternates from the served HTML, not the template.
- 2Fetch each alternate it names and confirm the set is identical in every one.
- 3Check every alternate returns 200 and is not redirected or noindexed.
- 4Confirm each page is canonical to itself rather than to another language.
- 5Verify the language codes are valid, and that a region code is paired with a language.
- 6Check the Search Console international targeting report for reported errors.
# Read the annotations one page declares
curl -s https://example.com/page \
| grep -oE '<link[^>]+hreflang="[^"]+"[^>]*>'
# Do the same on an alternate it names, and diff.
# The two lists must be identical, or Google ignores both.
curl -s https://example.com/de/page \
| grep -oE '<link[^>]+hreflang="[^"]+"[^>]*>'
When you should not use hreflang at all
A partially translated site is the common case, and the correct handling is to annotate only the languages that genuinely exist for each page rather than every language the site supports. For the canonical side of the same question see hreflang vs canonical , and for the wider setup see the international SEO checklist .
- A single-language site — there is nothing to annotate.
- Pages that are genuinely different content rather than translations.
- A set where only one version exists; a one-entry set says nothing.
- Machine-translated pages nobody reviewed, which are better not indexed than annotated.
How DomainLens contributes
DomainLens reads the hreflang annotations a page serves and reports them alongside its canonical, which is where the two most often contradict each other. For the language declaration on the page itself see the HTML lang attribute .
- Is hreflang a ranking factor?
- No. It determines which language version Google shows to which user. Each version still has to earn its own position.
- Why is Google ignoring my hreflang tags?
- Almost always missing return links. Every page in the set must list every other page including itself, or Google discards the whole annotation.
- What is x-default for?
- It names the version to show users whose language and region match no other entry — typically a language selector or the primary version.
- Should each language version be canonical to itself?
- Yes. Canonicalising translations to the original tells Google to drop them from the index, which defeats the purpose of translating them.