🌐 hreflang Tag Generator
Pick a base URL and target locales to generate <link rel="alternate" hreflang="..."> tags in bulk. Auto x-default, ISO 639 + country code validation, CSV bulk multi-path mode.
🔒 About Privacy
- ・URLs are never sent to any server
- ・All processing runs in your browser
- ・No signup, no login, no payment ever
Comma-separated. ISO 639-1 (en) or ISO 639-1 + ISO 3166-1 (en-US, zh-CN).
The locale settings above are applied to each URL.
📄 Generated tags
📖 Where people get stuck
Generates <link rel="alternate" hreflang="…"> tags from a base URL and a set of locales, supporting path-prefix, subdomain and query-parameter URL patterns, automatic x-default, and bulk generation from CSV. Everything runs in the browser. hreflang is not a ranking factor — it merely declares that another language version of the same content exists here, and helps the search engine choose which one to show.
| Case | What happens | What to do |
|---|---|---|
| The set is ignored because the references are not mutual | hreflang only works when every page in the group points at every other — if the Japanese page points at the English one but the English one does not point back, Google discards the whole set. Easily missed is that each page also needs a hreflang tag pointing at itself: the Japanese page carries a hreflang="ja" entry for its own URL. The most common failure in practice is updating one page and forgetting the other languages — the operational burden that adding a new language means updating the tags on every existing page is the essential difficulty of this mechanism. |
Put the generated set of tags, unchanged, into the <head> of every language version — the content does not differ per page. As an implementation, looping over the language list in the page template is the only sane approach; writing them by hand always drifts somewhere. For a large site, consider declaring them in sitemap.xml rather than in HTML: <xhtml:link> expresses the same information, and having every page in one file makes a missed update structurally impossible. Verify in the International Targeting report in Search Console — a no return tags message there is exactly the missing mutual reference. |
| The language code is malformed | The value is a language, or a language plus a region; a region alone is not valid — hreflang="US" means nothing. Common errors include en-UK, where the correct code is en-GB, using bare zh and expecting it to distinguish simplified from traditional, and an underscore, as in ja_JP, where a hyphen is required. Chinese deserves particular care: simplified and traditional are distinguished by script codes, zh-Hans and zh-Hant. zh-CN and zh-TW also work, but being regions they do not match simplified-script readers in Singapore or Malaysia. |
The language code is ISO 639-1, the region code is ISO 3166-1 alpha-2, and the separator is a hyphen. More importantly, ask whether you need the region at all: hreflang="en" matches every English speaker, whereas hreflang="en-US" matches only English speakers in the United States. If your content and prices do not vary by country, omitting the region reaches more people. Reserve regions for pages where currency, shipping or legal requirements genuinely differ. A free hreflang checker is the reliable way to verify, but start by putting the HTML of two language versions side by side and confirming with your own eyes that they point at each other — most errors are caught right there. |
| A conflicting canonical keeps the other version out of the index | hreflang and canonical do different jobs and are easily conflated. Each language version must have a canonical pointing at itself. Set the canonical of /en/about/ to /ja/about/ and you have declared that the English page is a duplicate and only the Japanese one should be indexed — the English page disappears from search results. The hreflang set is then ignored as well, since a group whose canonicals point elsewhere is not trusted. It is the classic case of a well-intentioned setting — surely a multilingual site needs canonicalisation — producing exactly the opposite of what was wanted. |
Every language version must have a self-referencing canonical. hreflang says another language version exists; canonical says this page is itself the canonical one — they only work correctly together. Reserve canonical for duplicate URLs within the same language: with and without a trailing slash, URLs carrying tracking parameters, print views. Once implemented, check Google-selected canonical in the Search Console URL inspection — if it differs from your intent, that is hard evidence that your declaration is not getting through. |
Adding hreflang does not guarantee that every language version gets indexed. A page with a thin translation, or with raw machine translation, fails on quality regardless of hreflang — this site retired its Portuguese and German versions in July 2026 for exactly that reason: they were duplicates of the English pages with no value of their own, and 576 URLs were consolidated with 301 redirects. Before adding a language, ask whether the content is worth reading in that language; adding a pile of thin translations is a liability for the site as a whole. There are three places to declare it — the HTML <link>, an HTTP response header, or sitemap.xml — and any one of them suffices; combining them is allowed, but contradictions cause the whole thing to be ignored. For files with no <head>, such as PDFs, use the HTTP Link: header.
📖 How to Use
-
1
Enter base URLEnter the URL you want to localize.
-
2
Specify localesEnter target language codes comma-separated (en, ja, ko).
-
3
Get tagsPaste the generated <link> tags into each page <head>.
❓ Frequently Asked Questions
Is x-default required?
Where should hreflang go?
Are bidirectional links required?
🔗 Related Tools
🐛 Found a bug or issue with this tool?
Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.
Thanks for your report!
Your report has been delivered to the operator and will be used to improve the tool.