hreflang generator

Most generators emit whatever you type into them. This one checks the codes first — against the full ISO 639-1 and ISO 3166-1 lists — and tells you when a perfectly valid code is not the one you meant.

Free, no emailHead · HTTP header · sitemapNothing is sent anywhere

Your URLs

One row per language or country version. The self-referencing tags are added for you — they are the part people leave out.

hreflangURL

Checks

Against the whole of ISO 639-1 and ISO 3166-1, not a shortlist of the popular twenty.

    Output

    Pick one method. Two is worse than one, because the two drift apart.

    The rule that breaks everything

    Worth reading before you paste the output anywhere.

    If page A declares page B as an alternate and page B does not declare page A back, search engines throw the pair away. Not one tag — the pair. There is no error, no warning, and nothing in any report to show it happened.

    That is why this tool outputs one identical block for every URL in the set rather than a different block per page. Paste the same thing everywhere and the return tags cannot be wrong.

    What hreflang actually does

    An hreflang annotation tells a search engine that two or more URLs are the same page written for different languages or countries, so the right version is served to the right person. It is worth being precise about the limits, because most of the disappointment around hreflang comes from expecting more:

    • It is a hint about which version to show, not an instruction about what to index. Pages still have to earn their place on their own.
    • It does not improve rankings. What it fixes is the wrong version ranking, or two of your own versions competing for the same query.
    • It does not replace a canonical tag, and it must not contradict one. If the English page canonicalises to the Spanish page while also declaring it an alternate, you have given two opposite instructions and the annotation is ignored.

    Where to put the tags

    Three places are valid, and you should use exactly one of them:

    • HTML head. The usual choice. Every page carries the whole set, including the tag pointing at itself.
    • HTTP Link header. For files that have no head to put tags in — PDFs, images, feeds. Same content, delivered as a response header.
    • XML sitemap. One entry per URL, each listing the full set. Verbose, but it keeps the annotations in one file instead of scattered across thousands of templates, which is what makes it the easier option once you pass twenty-odd locales.

    Doing two of them is a common and avoidable mess. The head tags get updated during a redesign, the sitemap does not, and now the same URL is declared two different ways by two teams who have never spoken to each other.

    Codes that validate and still lose the market

    Syntax checkers pass all of these. They are wrong anyway, and they are the reason this tool carries the whole ISO list rather than a regular expression:

    WrittenWhat it actually meansWhat was meant
    en-UKNot valid — UK is only reserved in ISO 3166-1en-GB
    ukUkrainianen-GB
    euBasqueEurope — which hreflang cannot target at all
    es-LASpanish in LaosLatin America — use es, or the countries one by one
    es-419Not valid — 419 is a UN M.49 code, not ISO 3166-1as above
    ar-MEArabic in Montenegrothe Middle East — again, not a thing hreflang has
    en_USNot valid — the separator is a hyphenen-US
    USNot valid — a country cannot stand aloneen-US
    iwRetired code for Hebrewhe

    The pattern is that hreflang has no concept of a continent, a region or a trading bloc. There is a language and, optionally, a country. Everything on that list is somebody trying to express something the format simply does not have, and getting a valid code that means somewhere else.

    The order I would work in

    1. List the URLs first, then choose the codes. Doing it the other way round is how you end up with locales nobody has pages for.
    2. Use language-only codes unless a country genuinely differs. es serving all of Latin America beats es-MX, es-AR and es-CO pointing at three near-identical pages that then compete with each other.
    3. Check the canonical on every page. Each version canonicalises to itself. This is the single most common way a correct set of tags gets ignored.
    4. Deploy to every URL in the set at once. A partial rollout is a set of broken return tags, and the pairs stay discarded until the last page ships.
    5. Verify after it is live, by fetching the pages and comparing both directions. Not by looking at the template.

    What this tool does not do

    It generates and it validates codes. It does not crawl your site, so it cannot see whether the tags you paste actually ended up on every page or whether the return tags reciprocate in production. That is a different job, and it is the one worth doing after deployment — my international SEO audit checklist covers how I go through it, and the Spanish guide to hreflang works through the return-tag failure in detail.

    One more thing, since it illustrates the point: this page is paired with a Spanish version, and both sides declare each other. You can read the whole pair out of this page’s own <head> — three tags, en, es and x-default, byte-identical on both URLs. That is the entire rule, applied to the page you are reading.

    Questions

    An annotation telling search engines that several URLs are the same page in different languages or for different countries, so the right one is shown to the right person. It is a hint about which version to serve, not an instruction about what to index, and on its own it does not move rankings.
    One of three places, and only one: link elements in the HTML head, a Link HTTP response header, or xhtml:link elements in an XML sitemap. The head is usual; the header exists for files with no head, like PDFs; the sitemap is easier to maintain at many locales. Using two at once is how contradictory declarations appear.
    No. The ISO 3166-1 code for the United Kingdom is GB, so it is en-GB. UK is only reserved in the standard, and an annotation using it is ignored. It is the most common single error in hreflang, and nothing in a browser or CMS warns you.
    Almost always the return tag: A declares B, B does not declare A, and the pair is discarded with no error and no trace in any report. After that, the frequent causes are an invalid code, a relative instead of absolute URL, and an hreflang target that contradicts the page's own canonical.
    Not required, but worth having. It names the fallback for a visitor nothing in your set matches — a Dutch reader on an EN/ES/DE set, say. It usually points at the international or English version, or a selector page. If that page is not itself one of the alternates, it still has to carry the same set of tags.