Hreflang explained, without the mysticism

"Why is Google showing my English page to someone searching in French?" is almost always a hreflang problem — and almost always a small, silent one. Hreflang is a simple idea that fails quietly: get it slightly wrong and nothing errors, nothing warns you, search engines just stop honouring it. Here is what it does, the handful of ways it breaks, and how to check yours by hand.

Marketing and CRM in the Olmira admin

What hreflang actually does

A hreflang annotation is a hint on a page that says, in effect: "this URL and that URL are the same content, in different languages (optionally for different regions) — when someone searches in that language, consider serving them that URL instead." It's implemented as a set of tags (in the page's , or equivalently in an XML sitemap), one per language/region variant, all pointing at each other.

The failure modes behind almost every "wrong language" complaint

Hreflang mistakes share one trait: none of them throw an error anywhere. The page still loads. The tags are still present. They're just wrong in a way only a search engine — or a careful human check — notices.

Non-reciprocal tags If page A declares an alternate pointing to page B, but page B doesn't declare one pointing back to A, the pair is broken — and the documented behaviour across major search engines is to distrust or ignore non-reciprocal annotations rather than partially honour them. This is the single most common real-world hreflang bug, because it's easy to add a new language page and forget to update every other language's tag set to reference it.

Tags pointing at a non-canonical, redirecting, or 404ing URL An alternate has to point at the actual, live, canonical version of that language's page — not an old URL that now redirects, and not a URL that requires login or returns an error for a crawler.

Partial coverage across a cluster Hreflang set correctly on some pages of a translated section but missing on others produces an inconsistent signal across the cluster, which tends to erode trust in the tags that are correct.

Duplicate or conflicting tags from multiple sources On sites where more than one piece of code can inject head tags — a page-level script and a site-wide layout, say — a race between them can leave duplicate or contradictory hreflang tags in the final markup. This is a real, subtle class of bug precisely because it's invisible in a quick visual check of the rendered page; it only shows up reading the actual source carefully.

Hreflang without a matching sitemap entry Search engines use the sitemap as a crawl-priority signal; a URL that's declared as a language alternate but never appears in the sitemap can simply get crawled later, or less often, than the pages you're actually trying to rank.

How to check your own site, by hand

No special tooling is needed for a first pass. View the page source — the actual source, not just the rendered DOM — and find every tag. For two or three language pairs, confirm each one points back: if /page declares hreflang="es" pointing at /es/page, open /es/page and confirm it declares a tag pointing back at /page. Then confirm exactly one x-default exists and resolves to a working page, and that every URL in the set loads directly — no redirect, no 404 — and matches that page's own canonical. On a small site this manual pass catches the majority of real-world mistakes.

What a healthy hreflang setup looks like

1

Every variant, reciprocal

Every language version of a page lists every other language version — including itself — as an alternate, so the set is fully reciprocal, not a one-directional guess.

2

One x-default, always resolvable

Exactly one alternate is marked x-default, and it points at a real, working page — typically your default-language version.

3

Self-canonical per language

Each language version's own canonical tag points at itself, not at the default-language version — a page shouldn't declare itself both an alternate of, and canonical-duplicate of, another URL.

4

Generated, not hand-maintained

On any site past a handful of pages, hand-writing reciprocal tag sets across every language pair is exactly the kind of task that silently drifts. Generating the set from one source of truth (the page's declared language list) keeps every page's tags consistent by construction.

Site builder in the Olmira admin

How Olmira handles this

An Olmira site's hreflang and x-default alternates are generated from one source — the page's declared language list — the moment two or more languages are active. Reciprocity is a by-product of how the tags are built, not something authored per page, and the tags are emitted once, centrally, for every route — specifically to avoid the duplicate-and-racing-tag failure mode above.

x-default always resolves to the site's own unprefixed default-language URL, and every language version carries its own self-referencing canonical. Which languages to run, and how complete each one should be before it ships, stays your judgment — that's the multilingual structure guide; the tag mechanics are handled the same way on every page of the website builder.

Let the tags take care of themselves

Every language you add gets correct, reciprocal hreflang automatically — no hand-maintained tag lists.