Hreflang and Canonical Tag Generator

Put this in the head of every version


    

Where hreflang sets quietly stop working

Two errors account for most broken setups. The first is en-UK: region subtags are ISO 3166-1 alpha-2 codes, and the code assigned to the United Kingdom is GBUK is reserved in that standard but never assigned, so en-UK is not valid. The second is a one-way reference: page A lists page B, page B never lists page A. Google's rule is blunt — if two pages do not both point at each other, the tags are ignored. Neither reports an error anywhere: the markup sits in the head looking correct and does nothing.

Reciprocity is the whole mechanism

An hreflang annotation is a claim about somebody else's URL, so it only counts when both sides make it. Every page in a set must list every other page, and must list itself as well. A missing return link invalidates that pair, and enough gaps stop the group behaving as a set at all. The fix is structural: generate the block once from one URL list and output it unchanged everywhere rather than hand-editing templates. Alternates also have to be indexable — a URL that is noindexed, redirecting or disallowed in robots.txt cannot hold up its end.

Language, region and x-default

The language subtag is ISO 639-1 and required. The region subtag is ISO 3166-1 alpha-2, optional, and never valid on its own — hreflang cannot express a country without naming a language. A script subtag from ISO 15924 is allowed where a language needs one. Use a hyphen, not an underscore; the value is case-insensitive, though an uppercase region is the convention.

ValueMeaning
enEnglish, any region
en-GBEnglish, readers in the United Kingdom
zh-HantChinese, traditional script
GBInvalid — region with no language
en-UKInvalid — UK is not the assigned ISO code
x-defaultFallback when nothing else matches

A canonical tag overrides all of it

Each language version should carry a canonical pointing at itself. Canonicalisation is settled before hreflang matters: point the German page's canonical at the English URL and you have said the German URL is not the one to index, so it drops out and its annotations go with it.

The same list can be delivered three ways: link elements in the head, xhtml:link entries in an XML sitemap, or Link HTTP headers — the method Google suggests for non-HTML files such as PDFs, which have no head to put tags in. One method per page is enough; a second just adds another place for the list to drift.

What this markup is not: a ranking signal. It does not translate or geolocate anything, only tells a search engine which existing version to show to which audience. Generating the block is the easy half — confirming every alternate returns it means checking those pages too.

Share this tool with friends

Free to use, no sign-up, works on any phone.

Frequently Asked Questions

Why is my hreflang being ignored?

Missing return references are the usual cause: one page lists the alternates but the alternates never list it back, and Google is explicit that if two pages do not both point at each other the tags are ignored. The other common causes are a canonical pointing at a different URL, an invalid code such as en-UK, and alternate URLs that are noindexed, redirecting or blocked in robots.txt. Check reciprocity first, then the canonical on each variant.

Does every page need a self-referencing hreflang tag?

Yes. Each page in the set should include an hreflang entry for its own URL alongside the entries for the other versions. That keeps the block identical on every page, which is what makes it safe to generate once and reuse, and it leaves no ambiguity about which URL serves which language.

Is en-UK valid, or should it be en-GB?

Use en-GB. Region subtags come from ISO 3166-1 alpha-2, where the code assigned to the United Kingdom is GB; UK is reserved in that standard but never assigned, so it is not a usable subtag. Language subtags come from ISO 639-1, and a script subtag from ISO 15924 is allowed where a language needs one, as in zh-Hant. The region part is optional, so plain en is fine when you are not targeting a country, but a region on its own is never valid.

Can I use a canonical tag and hreflang on the same page?

Yes, provided the canonical points at the page itself. Canonicalisation is settled before hreflang matters: a canonical aimed at a different URL says that other URL is the one to index, so the page carrying it drops out of the set and its annotations go with it. Self-canonical each language version and let hreflang describe the relationships between them.

What does x-default actually do?

x-default names the fallback URL for users whose language or region does not match any version you have listed. It is typically a language selector or a generic international page. It is optional; without one, a search engine still picks from the versions you did declare, but the choice is entirely theirs rather than a page you nominated.

Can hreflang go in the XML sitemap instead of the head?

Yes. There are three supported places: link elements in the HTML head, xhtml:link entries inside each url record in an XML sitemap, and Link HTTP headers, which is what Google suggests for non-HTML files such as PDFs that have no head to put tags in. The rules do not change: whichever you pick, every URL still has to list every alternate, including itself.

Everything on this page runs inside your own browser. Nothing you type or upload is sent to a server, so your data never leaves your device.