hreflang for Multilingual Sites
Serve the right language or region version with hreflang annotations.
hreflang tags tell search engines which language and region each version of a page targets, so users see the correct one.
Rules
- Use ISO language codes, optionally with a region (
en,en-GB,es-MX). - Annotations must be reciprocal - every version links to all the others, including itself.
- Add an
x-defaultfor a fallback version.
Where to place them
You can add hreflang in the HTML head, in HTTP headers, or in the XML sitemap. Pick one method and be consistent.
Example
<link rel="alternate" hreflang="en" href="https://example.com/guide">
<link rel="alternate" hreflang="es" href="https://example.com/es/guia">
<link rel="alternate" hreflang="x-default" href="https://example.com/guide">When to use it
- A travel booking site uses hreflang to serve French speakers in France the /fr/ version and French-Canadian speakers the /fr-ca/ version of each page.
- An international e-commerce store uses hreflang x-default to designate its English homepage as the fallback for unsupported locales.
- A global news publisher audits hreflang annotations after noticing the German audience is landing on the English site, revealing missing return tags.
More examples
hreflang annotation in HTML head
Each hreflang annotation must be present on every alternate page and must form a complete, reciprocal set to be recognised by Google.
<head>
<!-- English (UK) — current page -->
<link rel="alternate" hreflang="en-gb" href="https://example.com/en-gb/shoes/">
<!-- French (France) -->
<link rel="alternate" hreflang="fr-fr" href="https://example.com/fr-fr/chaussures/">
<!-- French (Canada) -->
<link rel="alternate" hreflang="fr-ca" href="https://example.com/fr-ca/chaussures/">
<!-- Fallback for all other locales -->
<link rel="alternate" hreflang="x-default" href="https://example.com/shoes/">
</head>hreflang via XML sitemap
Declaring hreflang in the sitemap is the recommended approach for large sites where editing every page's head is impractical.
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>https://example.com/en-gb/shoes/</loc>
<xhtml:link rel="alternate" hreflang="en-gb" href="https://example.com/en-gb/shoes/"/>
<xhtml:link rel="alternate" hreflang="fr-fr" href="https://example.com/fr-fr/chaussures/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/shoes/"/>
</url>
</urlset>Validate hreflang reciprocal links
Fetching hreflang tags from each alternate URL and comparing them validates that all pages declare reciprocal annotations, preventing orphaned locale signals.
python3 - << 'EOF'
import requests
from bs4 import BeautifulSoup
def get_hreflang(url):
soup = BeautifulSoup(requests.get(url, timeout=5).text, 'html.parser')
return {t.get('hreflang'): t.get('href')
for t in soup.find_all('link', rel='alternate') if t.get('hreflang')}
urls = [
"https://example.com/en-gb/shoes/",
"https://example.com/fr-fr/chaussures/",
]
results = {u: get_hreflang(u) for u in urls}
for url, tags in results.items():
print(f"\n{url}")
for lang, href in tags.items():
print(f" hreflang={lang}: {href}")
EOF
Discussion