Hreflang is an attribute that tells search engines about the language and regional versions of a page. Without hreflang, Google may show a Spanish user the Russian version or index duplicates instead of the correct versions. This guide covers hreflang syntax, implementation methods, and common setup errors.
Why hreflang is needed
Multilingual and multiregional websites face several problems:
- Duplicate content — the same page in different languages may be treated as a duplicate
- Incorrect search results — a user in Germany gets the English version
- Diluted link equity — multiple URLs compete for the same query
Hreflang addresses these problems by explicitly telling search engines how the versions are related and which version is preferred for each language/region.
Hreflang syntax
Code format
The code consists of a language code (ISO 639-1) and optionally a region code (ISO 3166-1 Alpha 2):
| Code | Meaning |
|---|---|
| ru | Russian |
| en | English |
| en-GB | English (United Kingdom) |
| en-US | English (United States) |
| de | German |
| es | Spanish |
| x-default | Default version (when there is no matching locale) |
Three ways to specify hreflang
1. In HTML (link in head):
<head>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/page" />
<link rel="alternate" hreflang="en" href="https://example.com/en/page" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page" />
</head>2. In HTTP headers:
Link: <https://example.com/ru/page>; rel="alternate"; hreflang="ru",
<https://example.com/en/page>; rel="alternate"; hreflang="en",
<https://example.com/en/page>; rel="alternate"; hreflang="x-default"3. In an XML sitemap:
<url>
<loc>https://example.com/ru/page</loc>
<xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/page"/>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/page"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/page"/>
</url>One method is sufficient. HTML is recommended because it is the easiest to check and debug.
Implementation rules
1. Reciprocal links
Each version must link to all the others, including itself:
<!-- На странице /ru/page -->
<link rel="alternate" hreflang="ru" href="https://example.com/ru/page" />
<link rel="alternate" hreflang="en" href="https://example.com/en/page" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page" />
<!-- На странице /en/page — те же три ссылки -->Omitting a self-reference or a link to another version is a common mistake.
2. Absolute URLs
Google recommends absolute URLs. Relative URLs may work, but absolute URLs are more reliable:
<!-- Рекомендуется -->
<link rel="alternate" hreflang="en" href="https://example.com/en/page" />
<!-- Допустимо, но не рекомендуется -->
<link rel="alternate" hreflang="en" href="/en/page" />3. x-default
x-default specifies the default version, shown when the user's language/region does not match any available version. This is usually the English or international version:
<link rel="alternate" hreflang="x-default" href="https://example.com/en/page" />4. One set per page
All hreflang links for a page must be in one place. Do not split them into multiple blocks.
URL structures for multilingual websites
Subdomains
ru.example.com
en.example.com
de.example.comSubdirectories
example.com/ru/
example.com/en/
example.com/de/Country-code domains
example.ru
example.de
example.co.ukGoogle does not favor any particular structure. Consistency and correct hreflang implementation are what matter.
Complete markup example
A Russian page with English and German versions:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Услуги — Пример</title>
<link rel="alternate" hreflang="ru" href="https://example.com/ru/services" />
<link rel="alternate" hreflang="en" href="https://example.com/en/services" />
<link rel="alternate" hreflang="de" href="https://example.com/de/services" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/services" />
</head>
<body>
<!-- Контент -->
</body>
</html>Each of the three pages (ru, en, de) must have an identical set of four link tags.
Dynamic hreflang generation
For CMSs and frameworks, generate the markup based on the current page:
// PHP пример
$currentPath = $_SERVER['REQUEST_URI'];
$languages = ['ru', 'en', 'de'];
foreach ($languages as $lang) {
$url = 'https://example.com/' . $lang . $currentPath;
echo '<link rel="alternate" hreflang="' . $lang . '" href="' . $url . '" />' . "\n";
}
echo '<link rel="alternate" hreflang="x-default" href="https://example.com/en' . $currentPath . '" />';// Next.js (App Router)
export default function Layout({ params: { lang } }) {
const languages = ['ru', 'en', 'de'];
return (
<html>
<head>
{languages.map((l) => (
<link
key={l}
rel="alternate"
hreflang={l}
href={`https://example.com/${l}/${pathname}`}
/>
))}
<link rel="alternate" hreflang="x-default" href={`https://example.com/en/${pathname}`} />
</head>
<body>{children}</body>
</html>
);
}Checking hreflang
Use the hreflang checker on reChecker to audit the markup. The tool identifies:
- Missing reciprocal links
- Invalid language codes
- Missing x-default
- URL mismatches
For a comprehensive technical check of a multilingual website, use the reChecker technical audit.
Hreflang and canonical
Hreflang and canonical serve different purposes:
- Canonical — specifies the preferred version when content is duplicated (in the same language)
- Hreflang — connects versions in different languages
On a multilingual page, canonical usually points to the page itself:
<link rel="canonical" href="https://example.com/ru/page" />
<link rel="alternate" hreflang="ru" href="https://example.com/ru/page" />
<link rel="alternate" hreflang="en" href="https://example.com/en/page" />Do not canonicalize a Russian page to an English one, or vice versa — they are different content versions.
Hreflang and sitemaps
Sitemap with hreflang
If you use a sitemap for hreflang, every URL in the set must be included in the sitemap. One url block contains loc and all xhtml:link elements for each version.
Multiple sitemaps
For a large number of pages, use a sitemap index. Each sitemap in the index contains its own URLs with hreflang. The structure must be consistent.
Hreflang for partial content
Not every page is available in every language. For example, a blog may be available only in Russian, while services are available in Russian and English. Include only URLs that actually exist in the hreflang set. Do not link to nonexistent versions.
Regional variants of the same language
en-US, en-GB, and en-AU represent different regions but the same language. Hreflang distinguishes between them. Use region codes when the content is adapted for a region (currency, spelling, examples).
Checking and validation
Manual check
Open each page version and inspect its HTML. Make sure the link tags are present and identical on every page in the set.
Automated check
The hreflang tool on reChecker checks the markup and identifies errors in reciprocal links, codes, and x-default. It saves time during an audit.
Google Search Console
The “International Targeting” report shows hreflang issues if they affect indexing. Errors are displayed with recommendations.
Hreflang setup checklist
| Check | Status |
|---|---|
| All versions link to each other | |
| Each page links to itself | |
| x-default is specified | |
| Absolute URLs are used | |
| Language codes follow ISO 639-1 | |
| Region codes follow ISO 3166-1 (if needed) | |
| Markup is present on every page in the set | |
| No links to nonexistent versions | |
| Sitemap is updated (if used) |
Related materials
Learn more about promoting websites in different languages in the international SEO guide. Common hreflang errors and how to fix them are covered in the hreflang errors article. You can check the markup with the hreflang tool and the technical audit on reChecker.