Hreflang tags tell search engines which language or country version of a page to show a given searcher — the English-India page to someone in Bengaluru, the Portuguese-Brazil page to someone in São Paulo. They don't lift your rankings; they swap the URL that ranks so the right visitor lands on the right page. Get them wrong and Google quietly ignores your whole cluster, serving your UK page to Indian users and tanking engagement.
This guide covers the exact syntax, the three ways to implement hreflang, the return-tag and x-default rules people botch most, and how to validate the setup so it actually holds.
What hreflang tags do and why they matter
Hreflang is an HTML attribute (rel="alternate" hreflang="...") that maps a set of equivalent pages to their audiences. When you run the same content across markets — say /in/pricing, /uk/pricing, and /us/pricing — Google needs to know these are alternates of each other, not duplicates competing for the same query.
Without hreflang, two bad things happen. First, Google may treat near-identical English pages as duplicate content and pick one to show everyone. Second, even when all three rank, an Indian searcher might get served the US page with dollar pricing and a US phone number. Hreflang fixes the routing: the page still ranks on its own merits, but the annotation tells Google which one to display.
A crucial point that trips up most people: hreflang is not a ranking factor. It won't push you up the SERP. Its payoff is downstream — lower bounce rates, better conversions, and fewer users bailing because they hit the wrong currency or language. That's why it matters most for sites targeting SEO for multiple countries with overlapping languages.
ISO language and region codes explained
Hreflang values use two standards stitched together with a hyphen: language-REGION.
- Language uses ISO 639-1 two-letter codes —
en(English),hi(Hindi),pt(Portuguese),ta(Tamil). This part is mandatory. - Region uses ISO 3166-1 Alpha-2 two-letter country codes —
in(India),gb(United Kingdom),br(Brazil),us(United States). This part is optional.
So en targets every English speaker worldwide, while en-in narrows to English speakers in India. Case is technically insensitive, but the convention is lowercase language, uppercase region: en-IN. Search engines accept en-in too.
Three rules people break constantly:
- You cannot use a region code alone.
inis invalid. It has to been-in,hi-in, etc. India isn't a language. - The UK is
gb, notuk. The ISO 3166 code for the United Kingdom isGB. Usingen-ukis one of the most common silent failures. - Latin America Spanish is
es-419, not a country code. That419is a UN M.49 region code — a rare valid exception to the two-letter rule.
| Intended audience | Correct hreflang | Common wrong version |
|---|---|---|
| English, India | en-in |
in, en-IND |
| English, United Kingdom | en-gb |
en-uk |
| Portuguese, Brazil | pt-br |
br, pt-BRA |
| Spanish, Latin America | es-419 |
es-latam |
| Hindi, India | hi-in |
hindi, hi-IND |
| Any English speaker | en |
en- |
If you're building out locale targeting from scratch, pair this with proper international keyword research — the codes are useless if you're targeting a language nobody in that market actually searches in.
Three ways to implement hreflang
Google supports three methods. They're equivalent in effect — pick based on scale and page type. Never use more than one method for the same URL; conflicting signals confuse the parser.
1. HTML <head> tags
The most visible option. Each page lists every alternate, including itself, inside the <head>:
<link rel="alternate" hreflang="en-in" href="https://example.com/in/pricing" />
<link rel="alternate" hreflang="en-gb" href="https://example.com/uk/pricing" />
<link rel="alternate" hreflang="en-us" href="https://example.com/us/pricing" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
Great for small sites and easy to eyeball in the page source. The downside: every alternate multiplies the markup on every page. Ten locales means ten <link> tags on every single URL, which bloats HTML and gets unwieldy fast.
2. XML sitemap
The method that scales. You declare alternates using the xhtml:link element inside each <url> entry:
<url>
<loc>https://example.com/in/pricing</loc>
<xhtml:link rel="alternate" hreflang="en-in" href="https://example.com/in/pricing"/>
<xhtml:link rel="alternate" hreflang="en-gb" href="https://example.com/uk/pricing"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing"/>
</url>
All annotations live in one central file, so you're not editing templates for every locale. This is the recommended approach once you pass roughly 10 alternates per page. The catch: every listed URL must have its own <url> block with the full set of alternates repeated — sitemaps demand the same reciprocity as head tags.
3. HTTP headers
For non-HTML files — PDFs, docs, images — where there's no <head> to put tags in. You send hreflang in the Link HTTP response header:
Link: <https://example.com/in/guide.pdf>; rel="alternate"; hreflang="en-in",
<https://example.com/uk/guide.pdf>; rel="alternate"; hreflang="en-gb"
Rarely needed for standard pages, but the only option for downloadable assets you want to localize.
| Method | Best for | Weakness |
|---|---|---|
<head> tags |
Small sites, <10 locales | Bloats every HTML response |
| XML sitemap | Large multi-locale sites | Harder to spot-check manually |
| HTTP header | PDFs and non-HTML files | Needs server config access |
Return tags and the x-default value
This is where clusters break most often, so read carefully.
Every hreflang annotation must be reciprocal. If page A says "page B is my Portuguese alternate," then page B must say "page A is my English alternate." These are called return tags or return links. If B doesn't point back to A, Google treats the entire annotation as unverified and ignores it. There's no partial credit.
Each page must also reference itself. The /in/pricing page includes a self-referencing hreflang="en-in" pointing at its own URL. Miss the self-reference and the set is incomplete.
Then there's x-default. This value marks the fallback page for searchers whose language or region matches none of your listed versions. Someone browsing in Japanese who hits your English/Hindi/Portuguese cluster gets the x-default page.
Use x-default for:
- A language/country selector page (the classic use)
- Your global homepage with automatic geodetection
- Your primary market page when you have no dedicated selector
Include exactly one x-default per cluster. It's not mandatory, but skipping it means unmatched users get whatever version Google guesses is closest — usually wrong. If you run a locale switcher, see currency and language selector SEO for how to keep it crawlable.
Common hreflang mistakes that break clusters
Most hreflang failures come from a short list of repeat offenders:
- Missing return tags. The number-one killer. A points to B, B forgets A, Google voids the pair.
- Wrong region codes.
en-ukinstead ofen-gb, or a bareinwith no language. Silent — Search Console flags them as "unknown language code." - Relative URLs. Hreflang requires absolute URLs with protocol.
/uk/pricingis invalid; it must behttps://example.com/uk/pricing. - Pointing to non-canonical or redirected URLs. If your hreflang points at a URL that 301-redirects or has a canonical pointing elsewhere, Google discards the annotation. Hreflang URLs must be the final, canonical, 200-status version.
- Conflicting canonical tags. A page canonicalizing to a different locale contradicts its own hreflang set. Each locale page should self-canonicalize.
- Mixing implementation methods for the same URL — head tags and sitemap entries fighting each other.
- Blocking alternates in robots.txt. If Google can't crawl the target, it can't verify the return tag.
The deeper architecture matters too — hreflang sits on top of whatever URL structure you chose. If you're still deciding, read ccTLD vs subdomain and the broader multiregional website SEO approach before you hardcode locale paths, because migrating them later means rebuilding every annotation.
How to validate and monitor your hreflang setup
Hreflang is fragile, so treat validation as ongoing, not one-time.
Start with Google Search Console. The Crawl and Indexing reports surface hreflang problems, and errors like "no return tags" or "unknown language code" show up under the relevant reports. This is your source of truth for what Google actually sees.
Crawl the site with a dedicated tool. Screaming Frog, Sitebulb, or Ahrefs Site Audit all have hreflang modules that check for missing return links, non-canonical targets, and invalid codes across the whole cluster in one pass. Run this after every locale launch and on a monthly schedule.
Spot-check the response. For head-tag setups, view source and confirm the self-reference plus every alternate is present. For sitemaps, validate the XML and confirm each <loc> has its full reciprocal set. For HTTP headers, curl the URL and inspect the Link header.
Watch engagement by market. If your Indian traffic is landing on US pages, you'll see it in market-segmented bounce rates and conversion drops long before a crawler flags a broken tag. Segment your analytics by country and compare landing pages to expected locales. A rank tracker that supports DeployFlare's per-country tracking makes it obvious when the wrong URL is ranking in a market — you'll spot a mismatch as a sudden ranking URL change rather than digging through logs.
Once the cluster is clean, the work shifts from technical to editorial — see translating website content for SEO so each locale page earns its place rather than just existing as a tagged duplicate.
Hreflang isn't complicated once the rules click: correct codes, reciprocal return tags, one x-default, absolute canonical URLs, one method. The trouble is that a single broken link in a fifty-page cluster silently voids the pairs it touches — so build it carefully, validate it fully, and monitor it like the fragile thing it is.