How to Implement Hreflang Tags (3 Methods)
Step-by-step guide to implementing hreflang tags via HTML link elements, HTTP headers, and XML sitemaps. Choose the right method for your site.
There are three ways to implement hreflang tags: HTML link elements in the page head, HTTP response headers, and XML sitemaps. Each is fully supported by Google. Which one you use depends on your site's architecture and scale.
This guide walks through all three, with code examples and guidance on when to use each.
Before you start
Regardless of which method you choose, the rules are the same:
- Every page in a hreflang set must list all variants in the group
- Every page must include a self-referencing tag (linking to itself)
- All
hrefvalues must be absolute URLs - Language codes must follow ISO 639-1; region codes must follow ISO 3166-1 alpha-2
Don't mix methods without care
You can combine methods -- for example, HTML tags for your main pages and sitemap annotations for an archive -- but be consistent. Mixing creates complexity and increases the chance of errors.
Method 1: HTML link elements
This is the most common approach. You add <link rel="alternate" hreflang="..."> tags to the <head> of each affected page.
Identify your language/region variants
List every URL for each language or region version of a given page. For example, an English page at /en/about/ might have a French version at /fr/about/ and a German version at /de/about/.
Add link elements to every page's head
Each page in the set gets the full list of variants, including itself:
<!-- On /en/about/ -->
<head>
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/about/" />
<link rel="alternate" hreflang="de" href="https://example.com/de/about/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/en/about/" />
</head>
The same three links go on /fr/about/ and /de/about/ -- identical set, every time.
Verify self-referencing tags
Each page must include a tag pointing to its own URL. The /fr/about/ page must have hreflang="fr" pointing to itself, not just links to the other variants.
Validate your implementation
Crawl your site with an SEO tool or use a hreflang validator to check for missing return links, missing self-referencing tags, and invalid language codes.
Best for: Most websites. Standard HTML pages where you control the template.
Limitation: Requires a code change on every page. High page-count sites may find this cumbersome to maintain.
Generate your hreflang HTML automatically
Paste your URLs, pick your languages, and get copy-paste-ready link elements for every page.
Method 2: HTTP response headers
When you can't add HTML to a file -- PDFs, Word documents, PowerPoint files -- you implement hreflang via HTTP headers instead.
Configure your web server to send Link headers
In Apache, you can use mod_headers. In Nginx, use the add_header directive. The header format uses the same values as HTML, separated by commas:
Link: <https://example.com/en/report.pdf>; rel="alternate"; hreflang="en",
<https://example.com/fr/report.pdf>; rel="alternate"; hreflang="fr",
<https://example.com/de/report.pdf>; rel="alternate"; hreflang="de"
Apply the header to every affected file
Each PDF (or non-HTML resource) in the set needs the full Link header, just as each HTML page would need the full set of <link> elements.
Verify with curl
Test that your headers are being sent correctly:
curl -I https://example.com/en/report.pdf
Look for the Link: header in the response.
Best for: Non-HTML files (PDFs, documents) that have language variants.
Limitation: Requires server configuration access. Not available on all hosting environments.
Method 3: XML sitemap annotations
Large sites often manage hreflang via the XML sitemap rather than in each page's HTML. This keeps the signals in one place and avoids editing hundreds of templates.
Add the xhtml namespace to your sitemap
Your sitemap <urlset> element needs the xhtml namespace declared:
<?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">
Add xhtml:link elements to each url block
For every page in a hreflang set, include the full set of xhtml:link annotations inside that page's <url> block:
<url>
<loc>https://example.com/en/about/</loc>
<xhtml:link rel="alternate" hreflang="en"
href="https://example.com/en/about/" />
<xhtml:link rel="alternate" hreflang="fr"
href="https://example.com/fr/about/" />
<xhtml:link rel="alternate" hreflang="de"
href="https://example.com/de/about/" />
</url>
<url>
<loc>https://example.com/fr/about/</loc>
<xhtml:link rel="alternate" hreflang="en"
href="https://example.com/en/about/" />
<xhtml:link rel="alternate" hreflang="fr"
href="https://example.com/fr/about/" />
<xhtml:link rel="alternate" hreflang="de"
href="https://example.com/de/about/" />
</url>
Every URL in the set appears as its own <url> block, and every <url> block contains the full set of xhtml:link annotations.
Submit and monitor in Google Search Console
Submit your sitemap in Google Search Console. Check the Coverage report for any sitemap processing errors. If Google flags issues with hreflang, they'll surface here.
Best for: Sites with large page counts, CMS environments where modifying every page's HTML is impractical, or teams who prefer centralised management.
Limitation: If a page isn't in your sitemap or is excluded by robots.txt, the hreflang signals won't be read.
Choosing the right method
| Method | Best for | Requires |
|---|---|---|
| HTML head | Most websites, standard HTML pages | Template access |
| HTTP headers | PDFs and non-HTML files | Server configuration |
| XML sitemap | Large sites, CMS-driven sites | Sitemap control |
You can use more than one method, but avoid duplicating the same signals across HTML and sitemap -- it adds maintenance overhead without SEO benefit.
Related Articles
Part of Boring Tools -- boring tools for boring jobs.
Generate perfect hreflang tags
Create and validate hreflang markup for your multilingual site. Free.