Guides/Hreflang and International SEO: A Practical Guide
Guide

Hreflang and International SEO: Syntax, Reciprocity, and x-default

Hreflang has three non-negotiable rules: return tags must be reciprocal, every version self-references, and URLs are absolute. Learn the syntax and the common errors.

Hreflang tells Google which language and region version of a page to show to which user. It rests on three non-negotiable rules: return tags must be reciprocal (if X points to Y, Y must point back to X), every version must list itself and all its siblings, and every URL must be absolute and fully qualified. Break any one and Google ignores the cluster. The rest is choosing valid codes and putting the tags in the right place.

What hreflang does and where it sits in the stack

Hreflang is an annotation that maps equivalent pages across languages and regions. It does not change rankings on its own; it swaps the displayed URL so a German user sees your German page and a UK user sees your en-GB page. It is one signal among several. Google's geotargeting priority runs: ccTLD, then hreflang, then server IP, then on-page locale cues (address, phone, currency, language), then local links and Google Business Profile. Google ignores geotargeting meta tags entirely.

Your URL structure choice sets the foundation. From strongest geo signal to weakest: a country-code TLD (example.de), a subdomain (de.example.com), a subdirectory (example.com/de/, the low-maintenance default most sites should use), and URL parameters (?loc=de, not recommended). Whatever you pick, do not auto-redirect or swap content by IP address — Googlebot crawls mostly from the United States and may never see your regional variants. Serve distinct URLs, annotate them with hreflang, and offer a user-selectable language switcher instead.

Hreflang syntax and language-region codes

Each alternate is declared with a rel="alternate" link carrying an hreflang value:

<link rel="alternate" hreflang="en-gb" href="https://en-gb.example.com/page.html" />
<link rel="alternate" hreflang="de"    href="https://de.example.com/page.html" />
<link rel="alternate" hreflang="x-default" href="https://www.example.com/" />

The hreflang value is a language code, optionally followed by a region code:

Valid values: de, en-GB, de-CH, zh-Hant. Invalid values are a leading cause of ignored tags: a region alone (GB with no language), or non-standard inventions like es-419, EU, or UK (the correct code for the United Kingdom is GB). Crawlinx flags malformed values as hreflang.invalid_code.

Language targets a language regardless of country; a language-region pair targets speakers of that language in that specific country. Use de when the German page serves all German speakers; use de-CH only when you have a distinct Swiss-German variant.

Return-tag reciprocity

This is the rule that breaks most often. Hreflang annotations must be bidirectional: if your English page points to your German page, the German page must point back to the English page. Google treats the cluster as a set of mutual claims, and a one-way claim is untrustworthy — if page A says "my German equivalent is B" but B never confirms it, Google discards the annotation. Every page in the cluster must reference every other page in the cluster, including itself. Missing return tags are flagged as hreflang.no_return.

Self-referencing tags

Every version must list itself among its alternates. The English page includes an hreflang="en" entry pointing at the English page, the German page includes an hreflang="de" entry pointing at itself, and so on. A cluster where pages list their siblings but omit their own entry is incomplete and unreliable, because self-reference is what anchors each page's own language claim. Crawlinx flags the omission as hreflang.missing_self.

x-default

The x-default value names the fallback page for users whose language or region does not match any listed alternate — typically a language-selector page or your primary global version. It is not strictly required, but omitting it means users outside your defined set get whichever version Google guesses, rather than the landing page you chose. Declaring an explicit x-default is a small, reliable improvement for genuinely international sites. Crawlinx flags a cluster without one as hreflang.x_default_missing.

Hreflang in the head versus the sitemap

You can declare hreflang three ways, and you pick one — do not mix methods for the same cluster:

All three carry the same meaning; the sitemap approach simply moves the weight off the page. Whichever you choose, the reciprocity and self-reference rules apply identically.

Common errors

If your alternates live in a sitemap, keep that sitemap reachable — a robots.txt disallow on the sitemap or on locale directories can strand the annotations; see the robots.txt guide.

How Crawlinx detects hreflang problems

Crawlinx builds the hreflang graph across your crawled pages and flags broken reciprocity (hreflang.no_return), invalid language or region codes (hreflang.invalid_code), clusters missing the self-reference (hreflang.missing_self), a missing x-default (hreflang.x_default_missing), and pages lacking a matching lang attribute (i18n.lang_missing).

Takeaway

Hreflang works only when the graph is complete and honest: every page names itself and every sibling, every claim is returned, every URL is absolute, and every code is valid. Add an x-default for the users you did not target, keep hreflang and canonical in agreement, and on large sites move the annotations into the sitemap to keep pages light.

Related
Canonical Tags Guide: rel=canonical Explained Robots.txt Guide: How Robots.txt Works Crawl Budget: What It Is and How to Manage It hreflang.no_return hreflang.invalid_code hreflang.missing_self hreflang.x_default_missing i18n.lang_missing

Audit your own site — free

77 checks, internal PageRank, render-diff. No signup, results in ~30s.

Scan your site →