International SEO
Hreflang Guide: How to Set Up Multilingual SEO Right
Hreflang is a signal that tells Google which language or regional version of a page to show each user. Add it with HTML link tags, HTTP headers or an XML sitemap, with self-references and return links.
By SEORecheck Research Team, SEO auditorsPublished 9 min read
Hreflang is an HTML attribute (also usable in HTTP headers and XML sitemaps) that tells search engines which language or regional versions of a page exist, so each user sees the right one in search results. It does not boost rankings; it swaps the correct URL into the results and reduces duplicate-content confusion between translations.
If your site has an English, Ukrainian and Spanish version of the same page, hreflang is how Google knows that /pricing, /ua/pricing and /es/pricing are one "cluster" of alternates rather than three competing pages. This guide covers when you need it, exact syntax, the three implementation methods, URL structure choices and how to audit it.
What is hreflang and what does it actually do?
Hreflang was introduced by Google in 2011 to handle sites that serve the same content in different languages or to different regions. Google, Yandex and Naver use it; Bing has historically relied more on the content-language meta tag and other signals, so don't assume every engine reads it the same way.
When Google understands your hreflang cluster, it can:
- Show the Spanish URL to a user searching in Spanish, even if the English page has more links.
- Treat near-identical regional pages (for example,
en-USanden-GBwith different prices) as alternates instead of duplicates. - Consolidate signals across the cluster so the right version surfaces.
What hreflang does not do: it is not a ranking factor, it does not translate anything, it does not force Google to index a page, and it does not override a canonical that points elsewhere. Google Search Central describes it as a signal, not a directive, so broken or contradictory annotations are simply ignored.
When do you need hreflang?
Use hreflang when you have the same or equivalent content in more than one language or for more than one region. Typical cases:
- Full translations: an English site with Ukrainian and Spanish versions.
- Same language, different regions:
en-US,en-GBanden-AUpages with different currency, spelling or shipping details. - Partially translated sites: only the main template (navigation, footer) is translated while the core content stays the same. Google says this still qualifies.
You do not need hreflang for a single-language site, for pages that have no equivalent in another language, or as a fix for thin, auto-translated content. If a translated page isn't good enough to rank on its own, hreflang won't save it.
Which language and region codes should you use?
Hreflang values use an ISO 639-1 language code, optionally followed by an ISO 3166-1 Alpha-2 region code, separated by a hyphen. The language is mandatory; the region is optional. You cannot specify a region alone.
| Value | Meaning | Valid? |
|---|---|---|
en |
English, any region | Yes |
en-GB |
English for the United Kingdom | Yes |
en-UK |
"UK" is not an ISO 3166-1 code | No (use en-GB) |
uk |
Ukrainian language | Yes |
ua |
Not a language code (UA is the country) | No (use uk) |
uk-UA |
Ukrainian for Ukraine | Yes |
es |
Spanish, any region | Yes |
es-419 |
Spanish for Latin America (UN M.49 region) | Accepted by Google |
es-MX |
Spanish for Mexico | Yes |
de-AT |
German for Austria | Yes |
zh-Hant |
Chinese, Traditional script | Yes |
US |
Region only | No |
x-default |
Fallback for unmatched users | Yes |
The uk/ua confusion is one of the most common errors on Ukrainian sites. Your URL folder can be /ua/ (that's a URL decision, not a code), but the hreflang value must be uk or uk-UA. Codes are case-insensitive, though en-GB is the conventional style.
What is x-default and when should you use it?
x-default tells Google which URL to show when a user's language or region doesn't match any version you've declared. It is usually your language selector page or your main international version.
Example: your site has English, Ukrainian and Spanish. A user searching in German matches none of them. With x-default pointing to the English homepage, Google has a clear fallback. Without it, Google chooses on its own, which usually still works but gives you less control.
Use x-default on every page in the cluster, pointing to the same fallback URL. It's recommended, not required, and it is especially useful when you have a country/language chooser at the root.
How to implement hreflang: three methods
Google supports three equivalent methods. Pick one per page set; mixing them multiplies the chance of contradictions.
Method 1: HTML link elements in the <head>
The most common method for HTML pages. Each language version lists all versions, including itself:
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="uk" href="https://example.com/ua/pricing" />
<link rel="alternate" hreflang="es" href="https://example.com/es/pricing" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing" />
The same four lines must appear on /pricing, /ua/pricing and /es/pricing. Use absolute URLs with protocol, and place the tags in the <head> — an invalid element (like a stray <div> or an unclosed tag injected by a script) can end the head early and make Google ignore everything below it.
Method 2: HTTP Link header
Useful for non-HTML files such as PDFs:
Link: <https://example.com/guide.pdf>; rel="alternate"; hreflang="en",
<https://example.com/ua/guide.pdf>; rel="alternate"; hreflang="uk",
<https://example.com/es/guide.pdf>; rel="alternate"; hreflang="es"
Method 3: XML sitemap
Best for large sites, because it keeps the markup out of page templates and is easier to generate from a database:
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/pricing</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing"/>
<xhtml:link rel="alternate" hreflang="uk" href="https://example.com/ua/pricing"/>
<xhtml:link rel="alternate" hreflang="es" href="https://example.com/es/pricing"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing"/>
</url>
<!-- repeat a <url> entry for /ua/pricing and /es/pricing with the same links -->
</urlset>
Every URL in the cluster needs its own <url> entry with the full set of alternates.
Which method should you choose?
| Method | Best for | Main drawback |
|---|---|---|
HTML <link> |
Small and mid-size sites, CMS templates | Adds page weight; easy to break with JS or plugins |
| HTTP header | PDFs and other non-HTML files | Hard to maintain and inspect |
| XML sitemap | Large sites, many languages | Errors are invisible on the page; sitemap must stay in sync |
Self-references and return links: the two rules people break
Self-reference: each page must include an hreflang entry pointing to itself. The English page lists hreflang="en" with its own URL.
Return links (reciprocity): if page A says page B is its Spanish alternate, page B must link back to page A. Google ignores one-way annotations because anyone could otherwise claim to be an alternate of your page. In practice, the whole cluster should carry an identical set of hreflang tags.
A quick test: pick any URL, read its hreflang set, open each alternate and confirm it shows the same set. If a single URL in the chain redirects, returns 404 or is noindex, that pair breaks.
How do hreflang and canonical tags work together?
Every language version should have a self-referencing canonical and list the others via hreflang:
<!-- On https://example.com/es/pricing -->
<link rel="canonical" href="https://example.com/es/pricing" />
<link rel="alternate" hreflang="en" href="https://example.com/pricing" />
<link rel="alternate" hreflang="uk" href="https://example.com/ua/pricing" />
<link rel="alternate" hreflang="es" href="https://example.com/es/pricing" />
The classic mistake is canonicalising all translations to the English page. That tells Google the Spanish page is a duplicate that shouldn't be indexed, so hreflang has nothing left to swap in. Hreflang URLs should always be canonical, indexable, 200-status URLs.
Which URL structure is best for multilingual SEO?
Hreflang works with any structure, but the structure affects maintenance, link equity and geotargeting.
| Structure | Example | Pros | Cons |
|---|---|---|---|
| Subfolders | example.com/ua/, example.com/es/ |
One domain's authority, easiest to run, one Search Console property | Weaker local signal than a ccTLD |
| ccTLDs | example.com.ua, example.es |
Strong country signal | Separate authority per domain, higher cost; ties content to a country, not a language |
| Subdomains | ua.example.com, es.example.com |
Easy to host separately | Often treated more like separate sites; more setup |
| URL parameters | example.com/?lang=es |
Quick to build | Not recommended by Google; fragile |
For most businesses targeting languages rather than specific countries, subfolders are the pragmatic choice. That is also how SEORecheck is organised: English at the root, Ukrainian under /ua/, Spanish under /es/. Note that Google Search Console's International Targeting report has been retired, so country targeting now comes from ccTLDs, hreflang, local content and links rather than a settings toggle.
Should you redirect users by IP or browser language?
No — not automatically. Google Search Central advises against redirecting users based on perceived language or location. Googlebot mostly crawls from US IP addresses and without an Accept-Language header, so an automatic redirect can hide your Ukrainian and Spanish pages from the crawler entirely. Users also get trapped: a Spanish speaker travelling in Germany doesn't want German.
Better options:
- Show a dismissible banner: "This page is also available in Español."
- Offer a visible language switcher that links to the equivalent page, not the homepage.
- Remember the user's explicit choice in a cookie, but keep every language URL directly reachable.
What are the most common hreflang mistakes?
| Mistake | What happens | Fix |
|---|---|---|
ua instead of uk, en-UK instead of en-GB |
Value ignored | Use ISO 639-1 language + ISO 3166-1 region |
| Missing return links | Pair ignored | Same hreflang set on every page in the cluster |
| No self-reference | Weaker or ignored cluster | Include the page itself |
| Canonical points to another language | Translation not indexed | Self-referencing canonical per version |
Hreflang to redirected, 404 or noindex URLs |
Broken pairs | Only final, 200, indexable URLs |
| Relative URLs | Misresolved targets | Absolute URLs with https:// |
| Language switcher links to homepage | Weak internal linking between equivalents | Link to the equivalent page |
Tags injected late by JavaScript or outside <head> |
Possibly missed | Render in the server HTML <head> |
| Mixing HTML tags and sitemap with different values | Conflicting signals | Pick one method |
| Auto-redirect by IP | Versions hidden from Googlebot | Banners and switchers instead |
How to audit hreflang on your site
A practical hreflang audit takes five steps:
- Crawl the site with a crawler that reports hreflang (Screaming Frog, Sitebulb or similar). Export every URL with its hreflang set, canonical, status code and indexability.
- Validate codes: flag anything that isn't a valid ISO language (and optional region), plus
x-default. - Check reciprocity and self-references: every target must return a matching set. Crawlers usually report "missing return links" directly.
- Check targets: all hreflang URLs must return 200, be canonical to themselves and not be
noindexor blocked by robots.txt. - Confirm in Google: use Search Console's URL Inspection to see the rendered HTML and Google-selected canonical for each version, and compare performance by country and page in the Performance report.
Then spot-check real results: search in each language (for example, using the hl parameter or a browser profile set to Spanish) and confirm the right URL appears. Hreflang is one part of a broader technical SEO audit; our SEO audit checklist lists the other checks to run alongside it.
Key takeaways
- Hreflang tells Google which language or regional version to show; it isn't a ranking boost.
- Use ISO 639-1 language codes plus optional ISO 3166-1 regions:
uknotua,en-GBnoten-UK. - Every page needs a self-reference and return links; add
x-defaultas a fallback. - Choose one method: HTML
<link>, HTTP header or XML sitemap. - Keep a self-referencing canonical on each language version.
- Don't auto-redirect by IP or browser language; use a switcher or banner.
- Audit regularly — hreflang breaks quietly when URLs change.
Check your hreflang setup
Hreflang errors rarely show up as a visible bug; you just see the wrong language ranking in the wrong market. If you'd like a second pair of eyes, request a free SEO audit preview — it shows your SEO score and several real issues with examples — or browse a sample report to see how international and technical findings are documented.