Command Palette

Search for a command to run...

Hreflang Generator: Get Your International SEO Tags Right the First Time

Hreflang Generator: Get Your International SEO Tags Right the First Time

T
Toolz Team
|Aug 23, 2026|20 min read

Part of the SEO Tools collection

I lost a solid afternoon to hreflang once. A client had a site in English and French, split across /en/ and /fr/, and their French pages simply would not rank in France - Google kept surfacing the English version to French searchers. The markup looked correct. It was in the head, the codes were there, the URLs resolved. The problem, it turned out, was that the English pages pointed to the French ones but the French pages did not point back. Hreflang has to be reciprocal, and Google was throwing the whole cluster away because the return tags were missing. Nothing in the browser told me that. No error, no warning - just pages quietly failing to rank where they should.

That is hreflang in a nutshell. The concept is simple: tell search engines which language and regional version of a page to show which users. The execution is a minefield of ISO codes, casing conventions, reciprocity rules, and a fallback tag half the internet forgets about. I build and maintain multilingual sites often enough - across toolz.dev, WP Adminify's documentation, and various Laravel and React projects - that I wanted a tool that would generate the tags and catch the mistakes before they shipped. That is the Hreflang Generator, and this guide is everything I wish I had known that afternoon.

For the concept rather than the tool, start with hreflang tags explained, which is the hub for this topic and links out to the pieces on x-default, common hreflang errors, and framework setups for Next.js and WordPress.

TL;DR: hreflang tags tell search engines which language/region version of a page to serve each user, using the rel="alternate" hreflang="x" annotation. Codes follow ISO 639-1 (language) and ISO 3166-1 (region) - so the UK is GB, not UK. Tags must be reciprocal (every page links back), and you should include an x-default fallback. The generator outputs valid tags as HTML links, XML sitemap entries, or an HTTP header, validates every code, catches duplicates, and runs 100% in your browser.

What are hreflang tags and when do you need them?

An hreflang tag is an annotation that says "there is another version of this page for a specific language and region, and here is its URL." The syntax is <link rel="alternate" hreflang="fr-CA" href="https://example.com/fr-ca/" />, where fr-CA means French as spoken in Canada. When Google understands these relationships, it can serve the Canadian French page to a French speaker in Canada and the US English page to someone in the States, instead of guessing or defaulting to whichever version it happened to crawl first.

You need hreflang whenever you have substantially the same content in more than one language, or the same language targeted at more than one region. A blog that exists only in English does not need it. A SaaS marketing site translated into six languages absolutely does. The middle case - one language, multiple regions, like separate US and UK stores that are both in English - is where hreflang is most valuable and most overlooked, because the pages look like duplicates to Google unless you explicitly declare them as regional variants.

The payoff is twofold. First, the right version ranks in the right market, which lifts click-through and conversion because users land on prices, currencies, and phrasing that fit them. Second, hreflang defuses the duplicate-content problem: instead of your near-identical regional pages competing with and cannibalizing each other, Google treats them as one cluster of alternates and picks the best fit per query.

Why do the codes trip everyone up?

Because they follow standards, not intuition, and the standards have edge cases.

The values are BCP 47 language tags, defined in RFC 5646, and Google's own localized versions documentation is the authority on which subset it accepts.

The language part is an ISO 639-1 code: two letters, lowercase, like en, fr, de, ja. The optional region part is an ISO 3166-1 alpha-2 code: two letters, uppercase, like US, GB, DE. Put them together with a hyphen and you get en-US or de-DE. The conventions that bite people:

  • The United Kingdom is GB, not UK. UK is not a valid ISO 3166-1 code, and en-UK is a no-op.
  • Language comes first and is mandatory; region is optional and cannot stand alone. You cannot target US by itself - there is no such thing as region-only hreflang. It is always language, optionally narrowed by region.
  • Latin America uses a UN M49 code, es-419, because it spans many countries rather than one. This three-digit region code is valid and useful for "Spanish, Latin American variety."
  • Chinese often needs a script subtag, like zh-Hant (Traditional) or zh-Hans (Simplified), because the written form matters more than the country.

The generator validates all of this. It checks each code against the expected shape, normalizes the casing (lowercase language, uppercase region, titlecase script), and warns you when a subtag is not a recognized ISO language or region - so en-UK gets flagged before it wastes a crawl.

How do I use the Hreflang Generator?

The tool is built around a list of language versions and a choice of output format.

Step 1 - Add your versions. Each row is a language/region code plus the full URL of that version. A quick-pick list offers the common codes (en-US, es-419, zh-Hant, x-default, and more) so you do not have to remember the exact casing. Add a row per version.

Step 2 - Include an x-default. Add a row with the code x-default pointing to your fallback URL. This is the version served to users whose language you have not explicitly targeted - often a language-selector page or your primary homepage.

Step 3 - Pick a format. Switch between HTML <link> tags for the page head, xhtml:link entries for an XML sitemap, or an HTTP Link header for non-HTML files. As you edit, the generator validates every code and URL, catches duplicate codes, and shows a per-row status table so you can see at a glance which entries are valid.

Step 4 - Copy and deploy reciprocally. Copy the output and - this is the part that matters - add the same complete set of tags to every URL in the group, including a self-referential entry. Then confirm the setup with the International Targeting report in Google Search Console.

Everything runs client-side, so your URL structure - which can expose your entire international architecture - never leaves the browser. That is the same privacy model behind every tool on the site, covered in the data privacy guide.

What does the output look like in each format?

Here is a worked example rather than a description. A store selling into the US, the UK, France and Latin America, with a language-selector page as the fallback. Five rows go in:

hreflang URL
x-default https://example.com/
en-US https://example.com/us/
en-GB https://example.com/uk/
fr-FR https://example.com/fr/
es-419 https://example.com/latam/

Note two things about that set before the output. en-US and en-GB are both English, differing only by market, which is the case hreflang exists for and the case most sites skip. And es-419 is the UN M49 region code for Latin America, which the tool accepts as valid rather than flagging, because a three-digit region is legal in a language tag even though it is not an ISO 3166-1 alpha-2 code.

HTML link tags, for the page <head>:

<link rel="alternate" hreflang="x-default" href="https://example.com/" />
<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="es-419" href="https://example.com/latam/" />

That exact block goes on all five pages, unchanged. Not "the other four" on each page: all five, including the page's own entry. That is what makes the annotations reciprocal.

XML sitemap entries, where the tool wraps the same set in a <url> element and uses your page URL as the <loc>:

<url>
    <loc>https://example.com/us/</loc>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/" />
    <xhtml:link rel="alternate" hreflang="en-US" href="https://example.com/us/" />
    <xhtml:link rel="alternate" hreflang="en-GB" href="https://example.com/uk/" />
    <xhtml:link rel="alternate" hreflang="fr-FR" href="https://example.com/fr/" />
    <xhtml:link rel="alternate" hreflang="es-419" href="https://example.com/latam/" />
</url>

The generator reminds you of the piece that lives outside the block it can produce: the <urlset> element needs the xhtml namespace declared, or every xhtml:link entry is ignored while the file still validates as a sitemap.

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xhtml="http://www.w3.org/1999/xhtml">

HTTP Link header, a single header value for files with no <head> to edit, such as a PDF:

Link: <https://example.com/>; rel="alternate"; hreflang="x-default", <https://example.com/us/>; rel="alternate"; hreflang="en-US", <https://example.com/uk/>; rel="alternate"; hreflang="en-GB", <https://example.com/fr/>; rel="alternate"; hreflang="fr-FR", <https://example.com/latam/>; rel="alternate"; hreflang="es-419"

It is one long line by design: a single Link header carrying comma-separated values. In nginx that is one add_header Link "..."; directive; in Apache one Header set Link "...". Splitting it across several Link headers also works, but keeping it as one value makes it obvious that the set is complete.

What do the generator's warnings mean?

The tool separates errors, which stop an entry being emitted, from warnings, which let it through but flag something you should look at. The distinction matters because most hreflang mistakes are legal markup that means nothing.

Message What triggered it What to do
Not a valid language tag The value does not match language[-Script][-REGION] Use a language code first, region optional, or the literal x-default
Language subtag is not a common ISO 639-1 code Well-formed but unrecognized language Check it against ISO 639-1; the tag is emitted either way
Region subtag is not a common ISO 3166-1 code Well-formed but unrecognized region This is what catches en-UK, where GB is correct
Duplicate hreflang The same code appears twice in the set Remove one; two entries for one code is a contradiction
No x-default set The set has no fallback row Add one pointing at a selector page or your primary version
hreflang works in clusters Only one URL in the set Add the other language versions; a one-entry cluster does nothing
hreflang must be reciprocal Always shown Deploy the identical block to every URL in the group

The last one is always displayed rather than conditionally, because it is the failure no client-side tool can detect. Reciprocity is a property of the other pages, not of the set in front of you, so the generator states the rule instead of pretending to verify it. Every other warning here is something it can genuinely check.

Note also that codes are normalized rather than rejected on casing: EN-gb becomes en-GB, zh-hant becomes zh-Hant. Language tags are matched case-insensitively, so the casing is convention, but consistent output makes a diff between two pages readable.

Which output format should I choose?

Google accepts three implementation methods, and the right one depends on your stack and page count.

Method Best for Trade-off
HTML <link> tags Most sites; direct control per page Adds weight to every page's head; must be on every page
XML sitemap xhtml:link Large sites; keeps HTML clean Requires maintaining sitemap; slower for Google to process
HTTP Link header Non-HTML files like PDFs Needs server config; harder to audit

For a typical site, HTML link tags are the most straightforward - you see them in the source, they are easy to debug, and every framework can render them. For large sites with hundreds of language variants, putting hreflang in the XML sitemap keeps your page heads lean and centralizes the annotations in one file (remember to add xmlns:xhtml="http://www.w3.org/1999/xhtml" to the <urlset> element, which the tool reminds you about). The HTTP header method is niche but essential for non-HTML resources like PDFs where there is no head to put a link tag in.

Whichever you pick, use only one method per set of pages. Mixing HTML tags and sitemap entries for the same URLs can send Google conflicting signals. If you are already generating a sitemap, the tool's sitemap format slots directly into the output from the XML Sitemap Generator.

What is x-default and why does it matter?

x-default is the hreflang value that specifies a fallback page for any user whose language or region you have not explicitly targeted. If your site has English, French, and German versions, and someone browsing in Japanese arrives, x-default tells Google where to send them - usually a neutral homepage or a page that lets them choose a language.

It is optional in the sense that hreflang works without it, but Google recommends including it, and I treat it as mandatory in practice. Without an x-default, unmatched users get whichever version Google guesses is closest, which is often just your most-crawled page rather than a deliberate choice.

For the tool's part: a set with no x-default row raises a warning rather than an error, so you can still copy the output, but you will have been told. Add the row and the fallback is emitted in whichever of the three formats you have selected, in the same position on every page. Where to point it, and the mistakes that make it useless, are covered in the x-default guide.

Why must hreflang be reciprocal?

This is the one that cost me an afternoon, so it gets its own section. Hreflang annotations must be reciprocal. If page A declares page B as its French alternate, page B must declare page A in return. Google only trusts the relationship when both sides confirm it. If the return tag is missing, Google ignores the annotation entirely - silently, with no error on the page.

The clean way to satisfy this is to put the full, identical set of hreflang tags on every page in the group, including a self-referential entry (the page pointing to itself). So on your en-US page, you include tags for en-US, en-GB, fr-FR, de-DE, and x-default - and the exact same block appears on the en-GB page, the fr-FR page, and so on. Every page in the cluster carries the whole map. It feels redundant, but it is what makes the annotations reciprocal and it is what Google expects.

This is why generating the tags is only step one. The free hreflang generator produces the complete block for you to reuse across the cluster, and it reminds you about reciprocity in its warnings, but the deployment discipline - same block, every page - is on you. Get that right and the codes right, and hreflang works quietly and reliably. Get it wrong and it fails just as quietly. For the broader context of assembling a technical SEO stack, I collected the related utilities in the web developer toolkit overview.

How do I test that hreflang is working?

After deploying, verify with the International Targeting report (historically called the hreflang report) in Google Search Console. It lists errors like "no return tags" and "unknown language codes" across your whole site, which is far faster than checking pages one by one. A crawl with an SEO auditing tool will also confirm that every page carries the full reciprocal set.

The mistakes I see most often, in rough order of frequency: missing return tags (the reciprocity failure above), no x-default, using UK instead of GB or other non-ISO codes, region-only tags that try to target a country without a language, relative URLs where hreflang requires absolute ones, and mixing implementation methods for the same pages. Every one of these produces markup that looks plausible and does nothing.

The hreflang tag generator is designed to catch the ones a machine can catch - malformed codes, unknown subtags, duplicates, non-absolute URLs, and the missing x-default - and to remind you about the ones it cannot enforce for you, namely reciprocity. The full catalogue, with the symptom each one produces, is in 12 common hreflang errors. If you are wiring hreflang into a larger multilingual build, the meta tag generator handles the rest of your per-page head, and the coding tools guide rounds out the developer workflow.

Which edge cases should you plan for?

Once the basics are in place, a handful of situations come up often enough to plan for. Canonical tags and hreflang have to agree. Each page's canonical should point to itself, not to a different language version - if your French page canonicalizes to the English one, you are telling Google to drop the French page entirely, which cancels out the hreflang you just added. Keep canonicals self-referential within a language cluster and let hreflang describe the relationships between clusters; hreflang vs canonical works through the combinations.

Language and country are independent axes. It is perfectly valid to have en-US, en-GB, and en-CA all in English but targeting different countries, and equally valid to have fr-CA and en-CA both targeting Canada in different languages. Do not assume one page per country or one per language; you are mapping the specific combinations your site actually serves.

Trailing slashes and protocols must match your real URLs. hreflang points at exact URLs, so https://example.com/fr/ and https://example.com/fr are different targets. Use the canonical, indexable form of each URL - the same one you would submit in a sitemap - so the annotation resolves to a live page rather than a redirect. A redirect in an hreflang target is not fatal, but it adds a hop and a chance for the signal to weaken, so it is worth getting exact.

Frequently asked questions

What is an hreflang tag?

An hreflang tag tells search engines which language and regional version of a page to show a given user. It uses the rel="alternate" hreflang="x" annotation, where x is a language code (optionally with a region), so a Spanish speaker in Mexico can be served your es-MX page instead of your English one. Hreflang helps international sites avoid duplicate-content problems and rank the right page in each market.

What is the correct hreflang format?

The value is an ISO 639-1 language code, optionally followed by a region as an ISO 3166-1 alpha-2 code - for example en, en-GB, or pt-BR. The language comes first and the region is optional; you cannot target a region alone. Note the standards differ from everyday abbreviations: the United Kingdom is GB, not UK.

What does x-default mean in hreflang?

x-default specifies the fallback page for users whose language or region you have not explicitly targeted. It is typically your homepage or a language-selector page. Google recommends including an x-default in every hreflang set so unmatched visitors are sent somewhere sensible rather than a random language version.

Where should I put hreflang tags?

You can implement hreflang in three places: as link rel="alternate" tags in the HTML head, as xhtml:link entries in your XML sitemap, or as an HTTP Link header (useful for non-HTML files like PDFs). Pick one method and apply it consistently - mixing them for the same pages can send conflicting signals. This tool generates all three.

Do hreflang tags have to be reciprocal?

Yes. If page A declares page B as its French alternate, page B must declare page A in return. Google ignores hreflang annotations that are not confirmed by return tags on the pages they point to. The simplest approach is to include the full, identical set of hreflang entries - including a self-referential one - on every page in the group.

Can hreflang tags fix duplicate content across regions?

Hreflang does not remove duplicate content, but it tells Google that similar pages are regional or language variants of one another rather than duplicates to filter out. This helps the correct version rank in each market instead of the pages cannibalizing each other. For genuinely identical pages, combine hreflang with correct canonical tags that each point to themselves.

How do I test that hreflang is working?

Use the International Targeting (or hreflang) report in Google Search Console, which lists errors such as missing return tags and unknown language codes. You can also crawl the site with an SEO auditing tool to confirm every page carries the full reciprocal set. Fixes can take time to reflect, since Google must recrawl every page in the group.

Is my data kept private?

Yes. The tags are generated entirely in your browser with plain JavaScript. Your URLs and site structure are never transmitted, logged, or stored, and the generator keeps working without a network connection once the page has loaded.


Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!