Hreflang Tag Generator
Add a row per localized page and get the full set of hreflang link tags - with x-default and self-referencing - ready to paste into your head.
- Free, no account
- No watermark
- No usage limit
About the Hreflang Tag Generator
Hreflang is the one SEO tag that breaks without ever telling you. There's no red error and no failed build, the page looks completely fine, and then weeks later Search Console reports "no return tags" and you learn Google threw the annotation out without a word. This generator exists to take that failure off the table. Add a row for each language or region version (a language code, an optional region code, and that version's URL) and it builds the full set of <link rel="alternate" hreflang="..."> tags as you type. One clean block, ready to paste onto every version. Set an x-default fallback, pick HTML, HTTP header, or XML sitemap output, hit copy. Nothing you enter leaves your browser.
Hand-written hreflang fails for a boring reason. Every page in the group has to carry the exact same list, pointing at every version including itself, and a person hand-editing ten <head> sections slips somewhere around page seven. Generate one block and stamp it on all of them, and the two rules that catch most people (reciprocity and the self-reference) are satisfied automatically, because an identical block already lists every version and its own URL. That is the entire workflow this tool is shaped around.
How to use
- Add a row per version. Each row is one localized page. Type the language code (
en,fr,de), an optional region code (US,GB,CA), and the full URL. The tool normalizes the case for you, soENandusstill come out asen-US. - Leave the region blank for language-only targeting. A row with
esand no region produceshreflang="es", which means Spanish for anyone who reads it, wherever they are. Only add a region when the content genuinely differs by country, like pricing or spelling. - Set the x-default URL. This is the page Google falls back to when a searcher matches none of your specific versions, usually a global homepage or a language picker. Leave it blank to skip it, though most multi-region sites want one.
- Pick the output format. HTML
<head>tags for a normal page, HTTPLink:headers for files that have no head like PDFs, or an XML sitemap block for large catalogs. - Copy, then paste on every version. The same block goes on all of them, including the page that points at itself. That last part isn't optional, and it's where most broken setups go wrong.
Paste the same block on every page
Google's rules for hreflang read like they were written to punish manual editing, and they were. Three of them do almost all the damage.
Reciprocity is the two-way handshake. If your English page says "my French version is over here," the French page has to say "my English version is over here" right back. Miss the return tag and Google drops the annotation entirely, it can't trust a one-sided claim (otherwise anyone could point hreflang at a competitor and hijack them). This is the single most common failure in Search Console, listed there as "no return tags."
Self-referencing means every page's block includes a tag for that page itself. Feels redundant, but skip it and Google can toss the whole set, because its documentation says the list on a page must contain the page's own URL.
The identical-set rule ties both together: every page in the cluster carries the same full list, the exact same URLs and codes. If English lists five versions and German lists four, Google sees a mismatch and may discard the lot.
All three collapse into a single action. Build one block that lists every version, then paste that same block on all of them. Reciprocity and self-referencing sort themselves out, because the block names every version, so wherever it lands that page's own URL and all its siblings are already inside. The identical-set rule can't break either, since every page carries a byte-for-byte copy. A generator is worth it the moment you pass two or three versions. Past that, hand-editing each page is where the return tags go missing.
Getting the codes right (and no, the UK isn't "UK")
Two standards, and Google is strict about both.
Language uses ISO 639-1, the two-letter list. en, fr, de, es, zh, ja, pt. Lowercase by convention, and the language is required, every hreflang value starts with one. Region uses ISO 3166-1 Alpha-2, the two-letter country list. US, GB, CA, BR, AU. Uppercase by convention, and optional.
The United Kingdom is GB, not UK, and that one catches almost everyone. Write en-uk and Google reads it as invalid and ignores the tag with no warning at all. So every code you type is checked against the real lists, all 184 languages and 249 countries, and a row holding en-UK says so underneath and tells you to write en-GB instead. Same for zz and eng, which look like codes and are not. The other thing it handles is the casing convention. Type the language in caps or the region in lowercase and it still emits en-US, so you never ship a lowercase en-us that has you second-guessing it later.
The region field takes a country, never a region of the world. There is no en-EU, since the EU isn't a country, and no es-LATAM. Simplified versus Traditional Chinese is a separate mechanism, a script subtag (zh-Hans, zh-Hant) most sites never touch.
HTML, HTTP header, or XML sitemap
Most free hreflang generators hand you the HTML <link> tags and stop there. This one gives you all three places the annotation can legally live, because which one you need depends on what you're tagging.
HTML <link> tags in the <head> are the default, easiest to read and debug, and right for any normal page. HTTP Link: headers exist for files that have no head to hold a tag, a PDF being the usual one, so the annotation is sent as a response header from your server instead. The XML sitemap format moves the whole thing out of your pages and into <xhtml:link> elements inside each <url> block, which is the sane approach when you're managing thousands of localized URLs and editing every head is a non-starter. One catch on the sitemap route, you have to declare xmlns:xhtml="http://www.w3.org/1999/xhtml" on the root <urlset> once, or the elements are invalid.
A URL with a query string is where a lot of quick generators fall down. If your href is https://example.com/p?id=7&lang=fr, that bare ampersand makes the tag invalid HTML. This one escapes it for you, so the tag you paste actually parses, whether the URL is clean or full of parameters.
Frequently asked questions
The tags are right there in my source, so why is Google ignoring them?
Almost always a canonical conflict or a broken return tag. If your hreflang points at a URL whose rel=canonical names a different page, you're telling Google "index this" and "don't index this" in the same breath, and it settles the contradiction by dropping the hreflang. Make each page canonical to itself, point hreflang at those canonical URLs, and confirm every version links back. Also give it time, hreflang applies on the next recrawl, which can be weeks rather than minutes.
When should I use `en` versus `en-US`?
Use plain en when one English page serves every English speaker. Reach for en-US only when you actually run separate English versions with real content differences, say en-US and en-GB with different currency and spelling. Splitting by region when the content is identical just creates maintenance and more places for a bug to hide, with no ranking benefit in return.
Does hreflang actually boost my rankings?
No, and it's worth being clear on this. Hreflang doesn't add ranking power to a page. It swaps which URL of your group gets shown to a given searcher, using the ranking that page already earned. The payoff is that the right person lands on the right-language page, which means lower bounce and fewer near-duplicate versions competing with each other, but you won't jump three positions from adding it.
Do the URLs have to be absolute?
Yes. Every href has to be a full https:// URL, protocol and domain included. A relative path like /fr/page is invalid in hreflang and gets ignored, so paste the complete address for each version. This also means a staging URL left in by accident points Google at your staging site, so give the output a quick read before it ships.
How do I handle Simplified versus Traditional Chinese?
Use zh-Hans for Simplified and zh-Hant for Traditional in the language field, because the difference is one of writing script rather than geography. The mistake to avoid is reaching for zh-CN and zh-TW as a stand-in, which pins each script to a single country and leaves Simplified readers in Singapore, say, unmatched. If Traditional genuinely differs between markets, append a region and use zh-Hant-HK for Hong Kong or zh-Hant-TW for Taiwan, keeping the script ahead of the region.
Why didn't one of my rows produce a tag?
The tool skips any row missing either its URL or its language code, because a <link> with an empty href or no hreflang is invalid and there's no reason to emit it. If a version you expected isn't in the output, check that both fields have content. The x-default is separate, it only appears once you fill in the x-default box near the bottom.
Can I mix HTML tags and sitemap annotations for the same page?
Better not to. Pick one method per page. If a page carries hreflang in its <head> and also in the sitemap and the two sets disagree, you've handed Google a conflict to resolve and it may trust neither. Choose the method that fits, page head for most sites, sitemap for big multilingual catalogs, and keep that page's annotation in that one spot.