To add hreflang tags, list every language or regional version of a page, give each one a language code (optionally with a region, such as en-GB), and then put the same full set of <link rel="alternate" hreflang="…" href="…"> lines in the <head> of every version, including a line for the page itself. If you can’t edit the HTML head, you can put the same information in HTTP headers or in your XML sitemap instead; Google treats all three methods as equivalent.
Key takeaways
- Hreflang goes on pages that have translated or regional equivalents on other URLs. One-language sites don’t need it.
- Use one method only: HTML head, HTTP headers, or sitemap. Google says combining them brings no benefit.
- Every version lists itself and every other version, with absolute
https://URLs. Pairs that don’t link back to each other are ignored. - Codes are an ISO 639-1 language, then an optional ISO 3166-1 Alpha 2 region:
fr,fr-CA,en-GB. Never a region alone. - Add
x-defaultfor visitors who match none of your versions. - On WordPress, Shopify and most translation tools, hreflang can be generated for you. Check it once, then re-check after theme or plugin changes.
Before you start: map your versions
Hreflang describes relationships, so you need the full list of related URLs before you write a single tag. Make a small table for each page type:
| Version | Code | URL |
|---|---|---|
| English (default) | en | https://example.com/pricing/ |
| French | fr | https://example.com/fr/pricing/ |
| French for Canada | fr-CA | https://example.com/fr-ca/pricing/ |
| Fallback | x-default | https://example.com/pricing/ |
Three decisions go into this table.
1. Language only, or language plus region? Use a bare language code (fr) unless the content really differs by country, for example in prices, currency, spelling or legal text. Google’s guidance is that when you have several regional versions of one language, it’s a good idea to also provide a generic version for speakers of that language in other places (Google Search Central). In the table above, fr catches French speakers in France, Belgium and everywhere else, while fr-CA is for Canada.
2. Which codes are valid? Google supports ISO 639-1 language codes and ISO 3166-1 Alpha 2 region codes, plus ISO 15924 script codes for cases like zh-Hant and zh-Hans. It states that other codes, such as es-419, aren’t supported, and that reserved values such as EU, UN and UK have no effect. For the United Kingdom, write en-GB. Our hreflang language codes list has the common ones in one place.
3. What is the fallback? x-default names the page for visitors whose language settings don’t match any of your versions. Google says it was designed for language selector pages and works best there, but many sites point it at their main-language page.
Also confirm each URL is the final address: it returns 200, isn’t redirected, and is its own canonical. Google’s canonical documentation says that when you use hreflang, you should specify a canonical page in the same language (Google Search Central).
Method 1: add hreflang tags to the HTML head
This is the method most sites use. Google recommends it when you don’t have a sitemap or can’t set HTTP response headers.
For the pricing page in the table, every one of the three versions gets exactly this block inside <head>:
<link rel="alternate" hreflang="en" href="https://example.com/pricing/" />
<link rel="alternate" hreflang="fr" href="https://example.com/fr/pricing/" />
<link rel="alternate" hreflang="fr-CA" href="https://example.com/fr-ca/pricing/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing/" />
Step by step:
- Open the template that outputs
<head>for that page type (in WordPress, usually the theme’sheader.phpor a hook; in a static site, the layout file). - Generate the block from data, not by hand. Hand-typed tags on hundreds of pages drift out of sync. Build the list from the same source that builds your language URLs.
- Include the current page in its own list. Google: “Each language version must list itself as well as all other language versions.”
- Use absolute URLs.
https://example.com/fr/pricing/, not/fr/pricing/or//example.com/fr/pricing/. - Keep each
<link>single-purpose. Google warns not to combine hreflang with other attributes such asmediain one tag. - Check the head is well-formed. The tags must be inside a valid
<head>. If a script or stray element breaks the head early, Google may not see them. Paste your rendered HTML into a validator if unsure.
Method 2: add hreflang with HTTP headers
Use headers for files that have no HTML head, such as PDFs. The server returns a Link: header listing every version, including the one requested, and the header is identical for every version:
Link: <https://example.com/guide.pdf>; rel="alternate"; hreflang="en",
<https://example.com/fr/guide.pdf>; rel="alternate"; hreflang="fr",
<https://example.com/guide.pdf>; rel="alternate"; hreflang="x-default"
URLs go inside angle brackets and entries are separated by commas. On Apache or nginx you set this per file or per location; on a CDN, with a response header rule. Test it with curl -I on each URL to confirm the header appears on all of them.
Method 3: add hreflang to your XML sitemap
A sitemap keeps all the annotations in one file, which suits large sites or teams that can’t change templates. The rules from Google’s documentation:
- Declare the namespace
xmlns:xhtml="http://www.w3.org/1999/xhtml"on<urlset>. - Create a separate
<url>entry for each version, with its own<loc>. - Inside each entry, add one
<xhtml:link rel="alternate" hreflang="…" href="…"/>for every version, including itself. Three versions means three entries, each with the same three children. - Order doesn’t matter, and the child links don’t count toward the sitemap URL limit.
<?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/pricing/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing/"/>
<xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/pricing/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing/"/>
</url>
<url>
<loc>https://example.com/fr/pricing/</loc>
<xhtml:link rel="alternate" hreflang="en" href="https://example.com/pricing/"/>
<xhtml:link rel="alternate" hreflang="fr" href="https://example.com/fr/pricing/"/>
<xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/pricing/"/>
</url>
</urlset>
Submit the sitemap in Search Console. Keep in mind that a sitemap can only list URLs under the directory where it is hosted, so a sitemap in /fr/ can’t list English pages at the root.
Which method should you choose?
| If your situation is… | Use |
|---|---|
| A CMS or site where you (or a plugin) control the head | HTML tags |
| PDFs and other downloads in several languages | HTTP headers |
| Thousands of URLs, or templates you can’t change | Sitemap |
| A platform or translation tool that generates hreflang | Its built-in output; don’t add a second set |
Google’s position is that the three methods are equivalent and that using all of them gives “no benefit in Search”, only more to maintain (Google Search Central).
Adding hreflang on common platforms
WordPress. WordPress itself has no multilingual layer, so hreflang comes from whatever creates your translated pages. Check your translation plugin’s settings before writing code, and make sure your SEO plugin doesn’t also output a conflicting set. If you use ConveyThis, see the section below.
Shopify. Shopify generates hreflang automatically from your Markets and language settings when each market or language has its own domain, subdomain or subfolder, and adds an x-default pointing to the primary domain. The feature is on by default and can be turned off in the Online Store preferences (Shopify Help Center). If you turn it off to manage tags yourself, you become responsible for keeping every set complete.
Static sites and custom apps. Generate the block in your layout from a single language map (a JSON or config file listing each locale and its URL pattern). Build the sitemap from the same map so the two never disagree.
A checklist before you publish
- The same set of tags appears on every version of the page.
- Every version includes itself.
- Every URL is absolute, returns 200, and is self-canonical.
- Codes are language first; regions are real ISO codes (
GB, notUK). - There is one
x-default. - Only one method is used.
- The page’s visible content is actually in the language the tag claims. Google detects language from the visible content, not from code (Google Search Central), so a “French” page that is mostly English won’t behave like a French page.
Because Search Console’s International Targeting report was retired in 2022 (Search Console Help), verify with a crawler that follows hreflang and reports missing return links. Google’s own page mentions Merkle’s hreflang testing tool and Aleyda Solis’s generator as popular third-party options it doesn’t maintain. If a tool says it found nothing at all, work through our guide to the “no hreflang tags” warning.
How ConveyThis adds hreflang for you
When you translate a site with ConveyThis and publish each language on its own subfolder (/fr/) or subdomain (fr.example.com), hreflang is generated automatically. On WordPress, the plugin prints the alternate links in the head of every page, one per language plus an x-default pointing to your original-language page, and includes the language alternates in its sitemap. The tags are built from the same language list and URL rules as the translated pages, so adding a language updates the whole set at once.
That leaves you two things to check: that your cache or optimisation plugin serves the head intact, and that no other plugin sets a canonical pointing translated pages back to the original. The multilingual SEO overview shows how translated URLs, metadata and hreflang work together, customising translated URLs explains how to localise slugs, and the WordPress integration page covers the plugin setup. For every edge case, from regional variants to pagination, see the complete hreflang implementation guide.
Frequently asked questions
Where exactly do hreflang tags go?
In the <head> of every language version of a page, as <link rel="alternate" hreflang="code" href="absolute-url"> elements. Alternatively, put the same information in an HTTP Link: header or in your XML sitemap.
Do I need a hreflang tag for the page itself?
Yes. Google requires each version to list itself as well as every other version. The set of links is identical on all versions.
Is en-UK a valid hreflang code?
No. UK is a reserved code and has no effect in Google Search. Use en-GB for English in the United Kingdom.
Should I add hreflang in the HTML and the sitemap?
No. Google treats the methods as equivalent and says using more than one brings no Search benefit while making the setup harder to maintain.
How long until Google uses new hreflang tags?
Google has to recrawl the pages involved, so it depends on how often your pages are crawled. Make sure all versions are indexable and linked from your site, and check the translated URLs with URL Inspection in Search Console.
Skip the manual work
Keeping hreflang complete across every page and language is easier when the same system creates the translated URLs and the tags. You can start with ConveyThis and connect your site.