Hreflang Generator

Paste your language and URL pairs, pick an x-default, and get a validated hreflang set as <link rel="alternate"> tags, sitemap xhtml:link entries and an HTTP Link header. Checks ISO 639-1 language, ISO 15924 script and ISO 3166-1 region codes, catches en-uk, region-only and three-letter codes, duplicate tags, relative URLs and a missing x-default — every page lists the whole cluster, so return links are guaranteed. Runs in your browser, nothing stored.

6 rows, 6 accepted. Separate with a comma, tab, semicolon or pipe; either order works; lines starting with # are ignored.

The page shown when no language matches — usually the language chooser or the main language. An explicit x-default row in the input overrides this.

6 tags in the set · 0 errors · 0 warnings

Findings (1)

  • InfoThe set spans 2 hosts. That is fine for ccTLD setups; check it is not a typo.

The set

hreflangLanguageScriptRegionURL
dedehttps://www.example.com/de/
enenhttps://www.example.com/
en-GBenGBhttps://www.example.co.uk/
jajahttps://www.example.com/ja/
trtrhttps://www.example.com/tr/
x-defaultfallbackhttps://www.example.com/

Output — the same set goes on every page

  <link rel="alternate" hreflang="de" href="https://www.example.com/de/" />
  <link rel="alternate" hreflang="en" href="https://www.example.com/" />
  <link rel="alternate" hreflang="en-GB" href="https://www.example.co.uk/" />
  <link rel="alternate" hreflang="ja" href="https://www.example.com/ja/" />
  <link rel="alternate" hreflang="tr" href="https://www.example.com/tr/" />
  <link rel="alternate" hreflang="x-default" href="https://www.example.com/" />

Paste inside <head> of every URL in the set — unchanged. Each page lists all alternates including itself, which is what makes return links complete.

Validation and rendering happen in your browser — no request leaves the page and nothing is stored. Language, script and region codes are checked against ISO 639-1, ISO 15924 and ISO 3166-1; the generator reports what it found and does not decide which markets need a page.

How it works

1. Read one entry per line — language tag and absolute URL in either order, separated by a comma, tab, semicolon, pipe or space; lines starting with # are ignored; an x-default row is optional
2. Split each tag into language, script and region (underscores are treated as hyphens) and normalise the case: language lower (en), script Title (Hant), region UPPER (GB)
3. Validate the parts — language against ISO 639-1 (two letters; iw/in/ji/mo flagged as deprecated), script against ISO 15924, region against ISO 3166-1 alpha-2; en-uk, a region on its own (us) and three-letter codes (eng) are rejected with the reason
4. Validate the URLs — absolute with http or https, parseable, no duplicate tag across rows; the same URL under two tags is allowed but flagged, a fragment (#) is flagged
5. Resolve x-default: an explicit row wins, otherwise the row you pick in the selector; more than one x-default is an error, none is a warning; the whole cluster, x-default last, is the output set
6. Render the same set once per page: <link rel="alternate" hreflang="…" href="…"> lines for the <head>, a sitemap <url> block with xhtml:link entries for every URL, and a Link HTTP header for non-HTML documents — because every page carries the full set, each page links back to every other and return links cannot be missing

About hreflang and what the generator checks

hreflang tells Google and Yandex which language and, optionally, which region a page is for, and where the equivalent page for other audiences lives. It is an annotation, not a redirect: the search engine still ranks whichever page it ranks, but when several versions of a page compete it can swap in the one that matches the searcher's language and country. Bing and most other engines ignore hreflang and read the HTML lang attribute and the content-language header instead, so hreflang complements those signals rather than replacing them.

A tag is a language code from ISO 639-1 — two letters, so en not eng — optionally followed by a script from ISO 15924 (zh-Hant, sr-Latn) and a region from ISO 3166-1 alpha-2 (en-GB, pt-BR). The order matters and so do the tables: the United Kingdom is GB, not UK; a region cannot stand alone; a tag like es-419 (Latin America) is a UN M.49 area code that Google does not accept. The generator normalises case, which search engines tolerate, and rejects the parts that are simply wrong, which they silently ignore.

The rule that breaks most implementations is reciprocity: if page A points to page B as its German version, page B must point back to A, and every page in the set must list every other page including itself. A missing return link makes Google ignore the annotation on both sides. The generator sidesteps the problem by construction — it renders the identical full set for every page, so the only way to get it wrong is to paste a different set on a different page. x-default names the page for visitors whose language matches nothing in the set, typically a language chooser or the primary language; it is optional, but a set without it leaves that decision to the search engine.

Three placements do the same job and you need only one: <link> tags in the <head>, xhtml:link entries in the XML sitemap (best for large sites, where editing templates per page is impractical and the sitemap is already generated), or a Link HTTP header, which is the only option for PDFs and other non-HTML files. Whichever you use, the URLs must be absolute and must be the canonical URLs — hreflang pointing at a redirected or non-canonical URL is dropped. The generator reports what it found; whether a market deserves its own page is a decision it does not make.

Frequently asked questions

Do I need x-default?
It is optional, but recommended when the set does not cover every language a visitor might have. x-default names the URL to show when none of the listed languages matches — usually a language selector or the main-language page. The generator warns when it is missing and lets you pick any row as x-default; an explicit x-default row in the input takes precedence over the selector.
Why is en-uk rejected?
Because the ISO 3166-1 code for the United Kingdom is GB. en-uk is the most common hreflang typo on the web; Google ignores the tag rather than guessing. The finding shows the corrected form, en-GB, so you can fix the source.
Can I use a language without a region, and a region on its own?
A language alone (de) is valid and matches every German speaker regardless of country. A region alone (de, meaning Germany, or us) is not valid — hreflang always starts with a language. To target Germany specifically use de-DE; to target German speakers in Switzerland use de-CH.
Is it a problem if two languages point at the same URL?
No. A single page can serve several tags — en and en-US on one URL, or a Spanish page for es, es-ES and es-MX — as long as each tag appears once. The generator flags a shared URL as information so you can confirm it is intended, but includes both tags in the output.
What does 'return links missing' mean in Search Console, and does this tool prevent it?
It means page A annotates page B but B does not annotate A. Every page in a set must carry the whole set, including a self-reference. This generator outputs the same complete block for every URL, so pasting it as given cannot produce a missing return link; the error appears only when pages are edited separately later or when a URL in the set redirects.
Should I put hreflang in the HTML, the sitemap or the HTTP header?
Pick one. HTML <link> tags are simplest for small sites; sitemap xhtml:link entries scale better and keep templates untouched; the HTTP Link header is the only option for non-HTML files such as PDFs. Using more than one placement is allowed but any disagreement between them is treated as an error, so it doubles the maintenance for no gain.
Does Bing use hreflang?
Bing states that it uses the HTML lang attribute, the content-language meta tag or HTTP header and the URL structure to determine a page's language and market, not hreflang. Google and Yandex read hreflang. Set both: hreflang for Google and Yandex, and a correct lang attribute for everyone else.