Hreflang tag generator: build the cluster for your language versions
List the versions of the same page, pick a format and take the finished block: head tags, HTTP headers or an XML sitemap, with x-default and a score that points at where the cluster leaks. Free, no signup, and nothing leaves your browser.
- - Versions
- - Languages
- - Tags generated
- - Block size
Finished block
What went into the score
- Valid language codes-
- Absolute URLs-
- No repeated code-
- No repeated URL-
- Everything on https-
- x-default declared-
- At least two versions-
- Consistent trailing slash-
Warnings
Everything runs in your browser: the list does not leave this page, no URL is fetched and nothing is stored. The score measures what is under your control, which is the shape of the codes and the URLs. It does not check whether the other end points back or whether the pages exist, because that would take a network call.
Who this page is for: anyone with the same content in more than one language who needs to declare it without breaking reciprocity. If what you want is the rest of the head of a single page, such as title, description, canonical and Open Graph, the place is the meta tag generator. If the subject is structured data, which is a different format with a different job, go to the FAQ schema generator. And if the question is about crawling the whole site, the path is the robots.txt generator. The scope here is one thing only: the link between the language versions of the same page.
Hreflang is the one head markup whose unit is not the page
Almost every SEO tag describes the page it sits on. Hreflang describes a group. It says that the Portuguese address, the English one and the Spanish one are the same page in different languages, and asks the engine to serve the right version to each person. The effect is not to gain a position: it is to swap which address appears in the position you already have, and to stop your own versions from competing with each other as if they were repeated content.
From that comes the rule that sinks most implementations: the block has to be reciprocal and it has to contain itself. Each version carries the whole list, its own URL included. When the English version points at the Portuguese one but the Portuguese one does not point back, the pair is never confirmed and is dropped in silence. That is why this generator does not produce the block for a single page: it takes the group and returns the block that is valid for all of them, identical on each. Pasting the same thing everywhere is the correct behaviour, not a shortcut.
How to use it
- Write one line per version, as code and URL separated by a space. Include the version you are editing: it belongs on the list too.
- Check the codes. The first value is the language in two lowercase letters, and the region is optional, in two uppercase letters, after the hyphen. The generator fixes underscores and letter case and tells you when it does.
- Pick the output format: head tags for most cases, HTTP headers for files that are not HTML, XML sitemap for large sites.
- Pick the version that answers for x-default, which serves the audience that matches none of the languages on the list.
- Check the score and the warnings, hit copy, and apply the block on every URL on the list, with no edits between one and the next.
How it works: what the score measures
The score runs from 0 to 100 and is the sum of eight checks, each matching a known way for a cluster to break. All of them are all or nothing, on purpose: hreflang has no useful middle ground, because an invalid code is not read halfway, it is simply not read.
Two checks tend to surprise people. The trailing slash one exists because many servers treat the address with and without the slash as different pages: when half the list has it and half does not, half the pairs point at a redirect, and hreflang that lands on a redirect does not count. The repeated URL one exists because the same page cannot answer for two languages: the two pairs cancel out and the crawler drops both.
Worked example (reproduces the default output)
The example already loaded is a pricing page in three languages, with x-default pointing at the English version. Reading the panel, number by number:
- 3 versions and 3 languages: English, Portuguese and Spanish, each with its region.
- 4 tags generated. Those are the three versions plus the x-default line, which is added to the others instead of replacing one of them.
- Score 100, band A, with the eight checks green and only the two standing reminders in the warnings list: the one about self reference and the one about reciprocity, which the tool cannot verify from this side.
Now change en-US on the first line to en-UK, which is the most frequent error with this attribute. With nothing else touched, the panel answers: the valid codes check falls to 0 of 22, the score drops to 78, the band goes from A to B, and the region trap warning appears explaining that the United Kingdom is GB. The other seven checks stay green and the tag count stays 4: the cluster does not collapse, it shows exactly what that one code cost.
Now switch the format to XML sitemap and look at the output: three URL blocks, one per version, each listing the same four tags. That is the full cluster, with reciprocity written in by construction, in a single file. It is exactly how the sitemap of this blog is built for its Portuguese, English and Spanish versions.
How to read each number
The score answers whether the block is ready to paste, not whether hreflang will work. It measures the shape, which is the part under your control; what decides the outcome is full reciprocity, and only the search engine sees all of that.
Version count against language count reveals a common case: five versions and two languages means the same language across several regions, such as en-US and en-GB. That is legitimate, and it is worth checking whether the content really differs between them. If it is the same text for both countries, a single version with no region often works better.
The tag count is the number of versions plus one when x-default exists. If it comes back equal to the version count, x-default did not make it in, and the matching check says so.
The warnings do not deduct points on their own: they explain the deduction the checks already made, and two of them always appear, even with a perfect score, because they are the two things no client side tool can verify for you.
Known limits
The tool checks shape, not existence. It does not visit the URLs, does not confirm that the page on the other side points back and does not read the canonical of each version, because all of that would take a network call and break the promise that your list never leaves the browser. After publishing, check with the URL inspection tool in Search Console or with a site crawler: that is where missing reciprocity shows up.
It is also worth knowing what hreflang does not do. It translates nothing, creates no version and improves no ranking. A machine translated page with no review is still weak content with correct markup. And if your versions live on different domains, the attribute works the same way, as long as they are all yours and reciprocity is kept between them.
Finally, support varies between search engines. Google uses the attribute as a signal, not as an order: it can ignore your instruction when other signals on the page contradict it, and the canonical is the strongest of those. Other engines weigh language and region their own way. Good markup raises the odds that the right version shows up, it does not guarantee that it always will.
From the pasted block to the test in the wild
Declaring the language is the beginning. Then comes the usual question, which is what happens to the people who arrive:
- Build the rest of the page head in the meta tag generator, and confirm that each version canonical points at itself.
- See how your result is drawn on search, with the exact cut off point, in the SERP snippet preview.
- Before deciding whether one version of the page converts better than another, check how much traffic the test needs in the sample size calculator.
- With the test live, read the verdict in the statistical significance calculator instead of calling it on the first good day.
- To see how AI answers treat what you publish in each language, run the GEO readiness checker.
Frequently asked questions
- What does hreflang actually do?
- It tells the search engine that two or more URLs are the same page in different languages or countries, so the right version is served to the right person. Hreflang does not change ranking: it changes which address shows up in the position you already hold. Someone searching from Brazil still finds the same page, only in Portuguese instead of English. Without the attribute, your own versions can compete with each other as near duplicate content, and the one that surfaces is whichever the engine considers strongest, which is not always the one in the searcher language.
- Do I really have to list the page itself in the block?
- Yes, and this is the most broken rule of the attribute. Every page in the group carries the whole list, including itself, which is called the self referencing tag. That is what lets the crawler confirm that all versions agree about the group. A block that only points at the other versions leaves the set unconfirmed and is usually discarded whole, with no warning anywhere. This generator produces a single block for exactly that reason: the same copy goes on every version, each one listing itself.
- Is x-default mandatory?
- It is not mandatory, but it solves a problem that shows up early. It marks the version served to people who match none of the languages on the list: someone in Germany, browsing in German, on a site that only has Portuguese, English and Spanish. Without x-default the engine picks one on its own. The most common choice is the English version, or a language selector page when one exists. A detail that confuses many people: x-default does not replace the tag for its own version, it is added to it, which is why the output carries one tag more than the number of versions.
- Can I use a country code alone, like br or uk?
- No. The first value is always the language, as the two letter ISO 639-1 code, and the region is optional and comes after it. hreflang="br" is not Brazil, it is Breton, the language of Brittany in France. hreflang="uk" is not the United Kingdom, it is Ukrainian. The United Kingdom is GB. The cruel part is that both values are syntactically valid, so no HTML validator complains and no error appears anywhere: the page is simply served to the wrong audience, and the problem gets discovered when someone asks why traffic from a market never arrived.
- Head tags, HTTP header or sitemap: which one should I use?
- All three are equivalent to the crawler, and the choice is operational. Head tags are the simplest when you control the page template. The HTTP header is the only option for files that are not HTML, such as a PDF published in two languages. The sitemap is the most efficient on large sites: the whole cluster lives in one file, no page HTML is touched, and it is far easier to review in bulk. Pick one and use only it. Declaring the same thing in three places adds nothing and multiplies the chance that one of them goes stale and contradicts the others.
- How many versions fit in the block?
- There is no practical limit in the attribute, and global sites run dozens of versions. What grows is the cost: a full cluster means one tag per version on every page, so thirty languages become thirty tags in the head of thirty pages. At that point the sitemap stops being a preference and becomes an architecture decision, because keeping thirty head templates in sync by hand is exactly where clusters break. If your version count passed ten, generate the sitemap format and treat it as a configuration file, not as hand written HTML.
- Does hreflang work if the canonical does not match?
- It does not, and that combination is the second most common cause of an ignored cluster. Every URL in the block has to be the one that page declares as its canonical. If the Spanish version has a canonical pointing at the English one, you are saying two contradictory things: that it is an independent language version and that it is a copy of the English page. Faced with the contradiction, the crawler follows the canonical and throws the hreflang away. The practical rule: a self referencing canonical on each version, and hreflang pointing at exactly those canonicals.
- Is anything I type here stored somewhere?
- No. Everything runs in JavaScript inside your browser: the list is parsed, the block is assembled and the score is computed on your machine, with no network call, and nothing is saved or logged. The tool also never visits the URLs you provide, which means it checks the shape of the addresses and not the existence of the pages. That matters when the site is not published yet and the list reveals a launch in another market. You can confirm it by opening the network tab while typing: no request goes out.
Keep reading
To see what changes between optimizing for search and optimizing for conversion, read CRO vs SEO, look at zero click search optimization and learn to write quotable blocks in FAQ content for AI citation.