When the same content exists at several URLs because it was translated, a crawler arriving at /fr/pricing cannot know which sibling URL a given searcher should receive. Hreflang annotations answer that with <link> elements in the head of every page in the group, each naming one language version and its absolute URL:
<link rel="alternate" hreflang="fr" href="https://example.com/fr/tarifs">
They also settle a second problem. Without annotations, two translated pages can be read as duplicates of each other, and whichever version the engine prefers is the one served. The annotation states which URL belongs to which audience. It does not lift a page's position, and it is treated as a signal rather than a command.
| Value | Means | Example |
|---|---|---|
| Language alone | Every speaker of that language, whatever country they are in | de |
| Language and region | That language as used in one country | de-AT, pt-BR |
| Language and script | Where one language is written in two scripts | zh-Hans, zh-Hant |
x-default | The URL for visitors covered by no other entry | often a language selector |
The language subtag comes from ISO 639-1 and the region subtag from ISO 3166-1 alpha-2. That second list is where guesses fail: the region for the United Kingdom is GB, so en-UK is not a valid label.
There is one x-default per set and its URL must be one of the pages in the group. The usual choice is a language selector or the global home page. The contract is symmetric: every page names every page, including itself. If /de/ lists /fr/, then /fr/ must list /de/ and itself, or the annotation is discarded for want of a return tag.
Head elements are the common form. The same relationship can go in an HTTP Link response header, which suits non-HTML resources such as PDFs where no head exists, or as xhtml:link entries inside a sitemap. The requirements do not change: absolute URLs, a complete reciprocal set, one self-reference per page.
This generator takes a canonical URL, rows pairing a code with a URL, and an optional x-default. Codes are lowercased on output and duplicates dropped, so a second row for a code you already listed disappears silently.
noindex page or a duplicate variant leaves visitors nowhere to land.en-EU and en-UK are common inventions. An unknown subtag invalidates the entry, and an invalid entry cannot pair with its opposite number, which breaks the reciprocity of the whole set.lang attribute. An annotation is a statement about other URLs; it does not identify the language of the page carrying it. <html lang="fr"> is a separate declaration with a separate job, and a page normally needs both.It is not a ranking signal in the sense of moving a page up. Its function is to route the right language version to the right audience and to help an engine tell translations apart from duplicates.
No. Country-code domains, subdomains and subdirectories all work, provided each locale has its own distinct, crawlable, absolute URL.
Yes, in the xhtml namespace inside each <url>. The set must still be reciprocal, and a page absent from the sitemap is absent from the group.
Yes. An annotation names a URL, so every version needs its own address. A page that swaps text client-side leaves nothing to point at.