# hreflang

`hreflang` annotations tell a search engine that several URLs are the same content in different languages or for different regions, so that a reader in one place is offered the version meant for them. The annotations form a set, and a set only works if every member names every other member — including itself.

- **Status:** Reference
- **Audience:** both, developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/technology/hreflang/

## The reciprocity rule, and why sets break

An hreflang set is a bidirectional graph. If page A says page B is its German alternate, page B must say A is its English alternate, and both must list themselves. A one-way declaration is discarded, silently, because the engine has no way to tell an intentional link from a mistaken or hostile one.

- Every URL in the set carries the **full set**, including its own self-reference.
- Every URL in the set must be **self-canonical**. A canonical pointing at another language collapses the set.
- Every URL must return **200** and be indexable. A `noindex` member removes itself and breaks reciprocity for the rest.
- The set must be declared consistently in **one** place — the HTML head, HTTP `Link` headers, or the sitemap — not partially in two.

> **Note** Sitemap declaration is the practical option for large sets. It keeps an N-language, M-page site from putting N annotations into every one of M×N documents, and it puts the whole graph in one file where a build can verify it.

## Language, region, and the codes people get wrong

| Value | Means | Note |
|---|---|---|
| `en` | English, any region | The common and usually correct choice |
| `en-GB` | English as served to readers in the United Kingdom | Region is a *targeting* hint, not a spelling claim |
| `hi` | Hindi | ISO 639-1 language code |
| `x-default` | The fallback for readers no other entry matches | Not a language. One per set at most |
| `en-UK` | Nothing — invalid | `UK` is not an ISO 3166-1 alpha-2 code; the country is `GB` |
| `en-EU` | Nothing — invalid | There is no region code for a continent or a union |

The second half of a value is a **region**, never a country of authorship and never a script. Marking a page `en-GB` does not tell an engine the page uses British spelling; it says the page is intended for readers in the United Kingdom. Where the only difference between two pages is spelling, they are usually one page, and the honest annotation is `en`.

> **Careful** Region-targeted variants with identical content are the most common wasted hreflang implementation. Five URLs that differ only in a currency symbol are five near-duplicates competing with each other, and the annotation manages the symptom rather than the cause.

## Does Connect use hreflang?

**Educational only.** This documentation corpus is published in one language, at one URL per page, and carries no hreflang annotations. There is nothing to relate: a set of one is not a set, and a self-referencing annotation on a page with no alternates adds a claim without adding information.

The page exists because the question arrives from a different direction. Connect handles many languages *in conversation* — a reply is written in the language of the message it answers, and voice work carries regional speaking style — and readers reasonably ask whether the same machinery applies to the website. It does not. Multilingual conversation and multilingual publishing are unrelated problems with unrelated solutions, and conflating them leads to expecting translated documentation that has not been written.

If the corpus is ever published in a second language, the honest implementation is the sitemap form with the set generated from the same page records — for the same reason the sitemap and the pages are generated together today. A hand-maintained hreflang graph is a reciprocity bug waiting for its first missed edit.

## Diagnosing a set that is being ignored

**No return tag** — B does not list A. The single most common cause, and it is usually one page in a set of forty rather than the whole set.
**Canonical conflict** — A German page canonicals to the English one. The engine consolidates them, and the alternate it was told about no longer exists as a separate document.
**Redirecting members** — An entry points at a URL that redirects by language detection. The crawler follows it somewhere else and the graph does not close.
**Mixed declaration** — Half the set is in the head and half in the sitemap. Neither declaration is complete on its own.
**Invalid code** — One `en-UK` in the file. Some engines drop that entry only; others distrust the group.
**Blocked member** — A member is disallowed in robots.txt, so its annotations are never fetched and reciprocity cannot be confirmed.

## Questions

### Do I need hreflang if my pages are in one language?

No. With no alternates there is nothing to annotate, and a lone self-referencing entry is noise. Add it when a second version genuinely exists as its own URL — not for a page that switches language with a client-side toggle, which has one URL and therefore one document.

### Is x-default required?

It is optional and it is usually a good idea. It names the page to offer a reader whose language or region matches nothing in the set — often a language selector or the most widely readable version. Without it, the engine chooses, and its choice may not be the one you would have made.

### Does hreflang affect ranking?

It is not a ranking factor. It influences which URL from a set is shown to a given reader once the set is already competing for a query. A weak page does not become strong by being annotated, and a strong page in the wrong language keeps ranking without the annotation, just for the wrong audience.

## Related

- [Canonical URLs](https://connectbyjbrh.com/docs/technology/canonical-url/)
- [XML sitemaps](https://connectbyjbrh.com/docs/technology/sitemap/)
- [Unicode, scripts and transliteration](https://connectbyjbrh.com/docs/technology/unicode-and-scripts/)
- [Multilingual voice](https://connectbyjbrh.com/docs/technology/multilingual-voice/)
- [robots.txt](https://connectbyjbrh.com/docs/technology/robots-txt/)

## What this page is based on

- Google Search Central — localised versions of a page, https://developers.google.com/search/docs/specialty/international/localized-versions
- RFC 8288 — Web Linking, the `alternate` relation and Link headers, https://www.rfc-editor.org/rfc/rfc8288
- Connect capability registry (docs-source/facts.py) — public_docs; no multilingual publishing capability is registered
