Hreflang implementation is where most international SEO goes wrong. The rules are finicky, the errors are silent (Google just ignores broken hreflang without telling you), and the stakes are high. Here's the detailed rulebook.
Most common. Add to <head> of every version of a page:
<link rel="alternate" hreflang="en-us" href="https://example.com/us/" />
<link rel="alternate" hreflang="en-gb" href="https://example.com/uk/" />
<link rel="alternate" hreflang="fr-fr" href="https://example.com/fr/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/us/" />
For non-HTML files (PDFs, images):
Link: <https://example.com/doc.pdf>; rel="alternate"; hreflang="en-us",
<https://example.com/uk/doc.pdf>; rel="alternate"; hreflang="en-gb"
Best for large sites:
<url>
<loc>https://example.com/us/page</loc>
<xhtml:link rel="alternate" hreflang="en-us" href="https://example.com/us/page"/>
<xhtml:link rel="alternate" hreflang="en-gb" href="https://example.com/uk/page"/>
<xhtml:link rel="alternate" hreflang="fr-fr" href="https://example.com/fr/page"/>
</url>
If page A links to pages B and C, then B must also link to A and C, and C must link to A and B. Non-reciprocation = Google ignores silently.
Page at URL X must include hreflang=".." href="X" in its hreflang cluster.
language-REGION (e.g., en-US, en-GB)en-us also worksen-uk, invalid. Use en-gb.zh-cn, valid but zh-hans (simplified Chinese) is more modern.sp-es. "sp" isn't a language code. Use es-es.Specifies the fallback version for users not matching any specific hreflang. Usually your default (US English).
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Each version should canonical to itself (not to another version). If your French page canonicals to your English page, you're telling Google "the English is the master", hreflang is overridden.
Never both on the same page. Conflicting signals.
If a hreflang target is 404, 301, noindexed, or blocked. Google drops the cluster.
en-US → https://example.com/us/
en-GB → https://example.com/uk/
en-CA → https://example.com/ca/
en-AU → https://example.com/au/
x-default → https://example.com/us/
If you don't differentiate by country:
en → https://example.com/
fr → https://example.com/fr/
de → https://example.com/de/
Be careful: "en" means "any English-speaking user." If you have US-specific content (prices in USD, US shipping), you want en-US not en.
fr-CH → https://example.com/ch/fr/
de-CH → https://example.com/ch/de/
it-CH → https://example.com/ch/it/
<head> (not in body)?Often silent. Search your pages in the markets they're supposed to serve. If the wrong version is ranking, hreflang is probably broken. Run through the debugging checklist.