Overview
Hreflang tells Google which version of a page to serve in which language and which country. It does not affect ranking; it affects which already-ranking URL appears for which user. A site with French, German, and US-English versions of the same article needs hreflang so the German user gets the German URL, not the French one. Without hreflang, Google picks one version and serves it to everyone, splitting traffic and confusing users. This page covers the syntax, the URL structure tradeoffs, and the error patterns that account for most broken implementations.
Use the correct language and region code
Hreflang values follow ISO 639-1 for language and ISO 3166-1 alpha-2 for region. Language alone is valid; region alone is not. Region must be paired with a language.
<!-- Language only: valid -->
<link rel="alternate" hreflang="fr" href="https://example.com/fr/article" />
<!-- Language + region: valid -->
<link rel="alternate" hreflang="fr-CA" href="https://example.com/fr-ca/article" />
<!-- Region only: invalid; Google ignores this -->
<link rel="alternate" hreflang="CA" href="https://example.com/ca/article" />Common codes: en, en-US, en-GB, fr, fr-CA, de, de-AT, es, es-MX, pt, pt-BR, zh-CN, zh-TW. Use the standard codes; en-UK is wrong (the country is GB).
Self-reference and pair every alternate
Every page in the cluster lists every alternate, including itself, and every alternate lists every page in the cluster including itself. The pairs must be symmetric or Google drops the cluster.
<!-- On https://example.com/en/article -->
<link rel="alternate" hreflang="en" href="https://example.com/en/article" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/article" />
<link rel="alternate" hreflang="de" href="https://example.com/de/article" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/article" />
<!-- The same four tags appear on /fr/article and /de/article -->Three rules from this example.
- Self-reference: the page lists itself. Required.
- Reciprocal: every alternate links back. If
/en/references/fr/but/fr/does not reference/en/, the cluster is invalid. x-default: the fallback for unmatched users. Required for clusters with three or more alternates; recommended otherwise.
Use x-default for the fallback locale
x-default is the version Google serves to users whose language or region matches no entry in the cluster. A French speaker in Brazil viewing a site with en, fr-FR, pt-BR gets fr-FR (language match); a Korean speaker gets x-default.
- Point
x-defaultat the English language or the international landing page that has its own region selector. - Do not omit
x-default; without it, Google guesses, and the guess is usually wrong. x-defaultis a value, not a language code. It can coexist withenoren-USin the same cluster.
Pick a URL structure and stick with it
Three URL structures support hreflang; pick one before launch and do not mix.
| Structure | Example | When it wins | When it loses |
|---|---|---|---|
| ccTLD | example.de, example.fr | Strongest geo signal; clearest brand per market | Most expensive; separate auth on each domain |
| Subdomain | de.example.com, fr.example.com | Cleaner separation than subdirectories; can host on different infra | Slightly weaker authority pooling than subdirectories |
| Subdirectory | example.com/de/, example.com/fr/ | Authority pools across the whole site; cheapest to ship | Weakest geo signal; Search Console geotargeting required |
For most sites, subdirectories on a single canonical domain are the right default. Use ccTLDs only when the brand or the legal entity is genuinely separate per country.
Ship hreflang in HTML or in the sitemap, not both
Two placement options; pick one.
- HTML
<link rel="alternate">tags in the<head>of every page in the cluster. - XML sitemap with
<xhtml:link>entries on every URL.
<url>
<loc>https://example.com/en/article</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/article" />
<xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/article" />
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/article" />
</url>The sitemap approach scales better on large sites and survives template drift; the HTML approach is easier to debug. Do not ship both; Google reads them independently and conflicts produce undefined behavior.
Know when hreflang does and does not help
Hreflang solves duplicate-content disambiguation across locales. It does not solve other problems.
- Helps: same content translated for different languages; same English content tuned for US, UK, AU markets; product pages with currency and shipping differences.
- Does not help: ranking a non-English page in an English query. The body language and the query language must match for that.
- Does not help: a page that exists in one language only. No alternates, no hreflang needed.
- Does not help: thin or auto-translated content. Hreflang surfaces the right version; it does not improve the quality of the version it surfaces.
Common errors
- Missing reciprocal pair. The most common bug; one page references the other, the other does not reference back. Run a hreflang validator on the full URL set before launch.
- Wrong language code.
en-UK(wrong) versusen-GB(right).cn(wrong; that is Cantonese language tag for some registries) versuszh-CN(right; Simplified Chinese for mainland China). - Conflict with canonical. The canonical and the hreflang point at different URLs; Google trusts the canonical and ignores the hreflang. Each locale page’s canonical points at itself, not at the English version.
- Hreflang to a noindex or redirected URL. The alternate must be indexable and return 200; otherwise the cluster breaks.
- Treating language and region as interchangeable.
frserves any French speaker;fr-CAserves only French speakers in Canada. A site withfrandfr-CAneeds both; a site with onlyfr-CAmisses French speakers in France. - Forgetting to update hreflang when adding a new locale. Adding
/it/means updating every existing locale page to reference it. See internal-linking on cluster-wide updates.