If your website offers content to users in various languages, countries, or regions, you can use a special markup to let search engines know who this content is for — and how the content should be presented to the specific users.
The hreflang attribute — also known as an HTML lang attribute — tells search engines like Google about these different variations.
Implementing hreflang helps the search engine point users to the most appropriate version of your page by language or region.
Note: Google and Yandex use the hreflang attribute, while Bing uses language meta tags.
Here is an example of hreflang in action. Suppose you search for “collectibles” on a search engine while you’re in the United States.
This is a search listing you may see:
If the same search is made in the United Kingdom, the results are different:
For pages that are optimized for multiple regions and languages, the hreflang tag must be included in the head section.
Recommended reading: Hreflang Present Outside <head>
Here is an example:
link rel="alternate" href="http://example.com/alternate-page " hreflang="x" />
Dissecting the code, we can learn quite a lot of information.
1. link rel=“alternate”: The link in this tag is an alternate version of this page.
2. hreflang=“x”: It’s alternate because it’s in a different language, and that language is x.
3. href=“https://example.com/alternate-page”: The alternate page can be found at this URL.
Here’s the example of code:
link rel="alternate" href="http://example.com/alternate-page " hreflang="en-us" />
This code tells Google that this English version of the page is specifically directed to an audience in the United States.
There are three different ways that you can tell a search engine about multiple language and location versions of a page.
You can alert Google for language and region variations of your page by adding <link rel="alternate" hreflang="lang_code"... > elements to your page’s header.
If you don’t have a sitemap or don’t have the ability to specify HTTP response headers for your site then this can be a useful option.
All page variations should have a set of <link> elements in the <head> element. (One link for each page variation including itself.)
Below, you’ll see the HTML that should be put in the <head> section of all the pages shown. Doing so would direct US, UK, generic English speakers, and German speakers to localized pages.
Google will return the appropriate result for the user, according to their browser settings.
You can return an HTTP header with your page's GET response to tell Google about all of the language and region variants of a page. This is useful for non-HTML files (like PDFs).
The format of the header looks like this:
Link: <url1>; rel="alternate"; hreflang="lang_code_1", <url2>; rel="alternate"; hreflang="lang_code_2", …
You must specify a set of <url>, rel="alternate", and hreflang values for every version of the page including the requested version, separated by a comma as shown in the example below.
The Link: header returned for every version of a page is identical.
HTTP/1.1 200 OK
Content-Type: application/pdf
Link: <http://example.com/file.pdf>; rel="alternate"; hreflang="en",
<http://de-ch.example.com/file.pdf>; rel="alternate"; hreflang="de-ch",
<http://de.example.com/file.pdf>; rel="alternate"; hreflang="de"
You can use a XML sitemap to inform Google of all of the language and region variants for each URL.
To do so, add a <loc> element specifying a single URL, with child <xhtml:link> entries listing every language/locale variant of the page including itself. So, if you have three versions of a page, your sitemap will have three entries, each with three identical child entries.
Here is an English language page targeted at English speakers worldwide, with equivalent versions of this page targeted at German speakers worldwide and German speakers located in Switzerland.
Here are all the URLs present on your site:
Here is the sitemap for those three pages:
<?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>http://www.example.com/english/page.html</loc>
<xhtml:link
rel="alternate"
hreflang="de"
href="http://www.example.com/deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="de-ch"
href="http://www.example.com/schweiz-deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="en"
href="http://www.example.com/english/page.html"/>
</url>
<url>
<loc>http://www.example.com/deutsch/page.html</loc>
<xhtml:link
rel="alternate"
hreflang="de"
href="http://www.example.com/deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="de-ch"
href="http://www.example.com/schweiz-deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="en"
href="http://www.example.com/english/page.html"/>
</url>
<url>
<loc>http://www.example.com/schweiz-deutsch/page.html</loc>
<xhtml:link
rel="alternate"
hreflang="de"
href="http://www.example.com/deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="de-ch"
href="http://www.example.com/schweiz-deutsch/page.html"/>
<xhtml:link
rel="alternate"
hreflang="en"
href="http://www.example.com/english/page.html"/>
</url>
</urlset>
The hreflang x‑default tag specifies the default or fallback page that gets shown to users when no other language variant is appropriate. You don’t have to use them, but Google recommends that you do. This is what one looks like:
<link rel="alternate" hreflang="x-default" href="https://example.com/" />
Google provides a list of guidelines to follow for localized page versions.
1. All language versions must include both the language variations and itself.
2. Alternate URLs must be fully-qualified.
3. Alternate URLs do not have to be in the same domain.
4. Consider including a catchall URL for geographically unspecified users of a language.
5. Tags will be ignored if two pages don’t point to each other.
6. Link newly expanded language pages bidirectionally to the originating language.
7. Add a fallback page for unmatched languages.
There are many potential issues that can arise with the hreflang tag. The below list is common issues found with hreflang.
If page A links to page B, then page B must also link back to page A. Annotations can be misinterpreted if the pages don’t have their appropriate return links.
You must include language codes with the ISO 639-1 format, and — optionally — the region with the ISO 3166 Alpha 2 format.
More on this issue: Invalid language in the Hreflang attribute
More on this issue: Hreflang Missing Language Entry
This happens when the URL in question has one or more incoming hreflang annotations that is invalid. This could be an invalid language or region code. Let’s look at an example.
If the URL is https://example.com/en/ and the below code was added to another region page …
<link rel="alternate" href="https://example.com/en/" hreflang="en-uk" />
… it is invalid because "en-uk" should be "en-gb."
More on this issue: Invalid region in the Hreflang attribute
This means that the URL in question has one or more outgoing hreflang annotation that is invalid (e.g. invalid language or region code).
If the URL is https://example.com/de/ and has the below code …
<link rel="alternate" href="https://example.com/en/" hreflang="en-uk" />
<link rel="alternate" href="https://example.com/fr/" hreflang="fr-fr" />
… it would be incorrect because “en-uk” should be “en-gb.”
More on this issue: Hreflang with Duplicate Language/Region Combinations
This means that the URL in question has at least one outgoing hreflang annotation URL which is noindex. Hreflang tags are interpreted by search engines as indexing instructions.
Suppose we have English and German pages. However, if the German page has a noindex tag, that means there is a directive to not index this page.
For the website: https://example.com/de/
<!doctype html>
<html lang="en">
<head>
<title>example</title>
<meta name="robots" content="noindex,nofollow">
<link rel="alternate" href="https://example.com/us/" hreflang="en-us" />
</head>
<body>...</body>
</html>
And we are going to have the following hreflang tag on the US page:
If the URL is https://example.com/us/
<!doctype html>
<html lang="en">
<head>
<title>example</title>
<meta name="robots" content="noindex,nofollow">
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
</head>
<body>...</body>
</html>
This means we are telling the search engine to index the DE page but, on that page, there is a noindex tag. This type of conflicting instruction serves to confuse search engines, to the point where they may ignore the hreflang completely.
This means that the URL in question is defined as an hreflang alternate, but is a no index. If you have an English (US) page which has hreflang pointing to German (DE) page, that means search engines are being instructed to index both the English and German Page.
However, if the English page also had a no index tag on it, this would be an instruction to not index the English page.
So, the hreflang is saying “please index the English page,” and the no index is saying “don't index the English page.”
This type of conflicting instruction serves to confuse search engines, to the point where they may ignore the hreflang completely.
This means that the URL in question has at least one outgoing hreflang annotation which returned as Not Found (4XX) or Error (5XX).
More on this issue: Hreflang URL Is Invalid
This means that the URL in question has at least one outgoing hreflang annotation which is canonicalized to another URL.
This means that the URL in question is defined as an hreflang alternate, yet is canonicalized to another URL.
More on this issue: Conflicting Hreflang and rel=canonical
This means that the URL in question has at least one outgoing hreflang annotation URL that is disallowed in robots.txt.
This means that the URL in question has multiple, different incoming hreflang annotations.
If, for example, the URL is https://example.com/de/ … the issue will be if this page had incoming hreflang from one page as:
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
... and if it also had incoming hreflang from another page, that is different to the above;
<link rel="alternate" href="https://example.com/de/" hreflang="fr-fr" />
More on this issue: Conflicting Hreflang and rel=canonical
This means that the URL in question has one or more outgoing hreflang annotations that specify the same URL, but with different hreflang, so there is a conflict between the two annotations.
If the URL is https://example.com/us/ ... the issue will be if the above URL had conflicting outgoing hreflang;
<link rel="alternate" href="https://example.com/de/" hreflang="fr-fr" />
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
More on this issue: Conflicting Hreflang and rel=canonical
This means that the URL in question has one or more self-referenced hreflang annotations that specify different hreflang values, so there is a conflict between the annotations.
If the URL is https://example.com/us/ ... there would be an issue if the URL had conflicting self referencing hreflang;
<link rel="alternate" href="https://example.com/us/" hreflang="en-us" />
<link rel="alternate" href="https://example.com/us/" hreflang="de-de" />
More on this issue: Hreflang with multiple defaults
This means that the URL in question has hreflang annotations that specify the same hreflang to multiple different URLs, so there is a conflict between the various annotations.
If the URL is https://example.com/us/ … there will be an issue if the URL had conflicting outgoing hreflang;
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
<link rel="alternate" href="https://example.com/es/" hreflang="de-de" />
More on this issue: Hreflang with multiple defaults
This means that the URL in question has hreflang annotations that have at least one outgoing hreflang annotation which is referenced as a relative URL.
If the URL is https://example.com/us/page-1/ ... there will be an issue if the URL had hreflang using relative URLs;
<link rel="alternate" href="/de/page-1/" hreflang="de-de" />
<link rel="alternate" href="/es/page-1/" hreflang="es-es" />
More on this issue: Hreflang Using Relative links
This means that the URL in question has hreflang annotations and HTML lang attributes that do not match.
If the URL is https://example.com/us/ … there will be an issue if the URL has an HTML lang attribute:
<meta http-equiv="content-language" content="en-gb">
... and a different hreflang value:
<link rel="alternate" href="https://example.com/us/" hreflang="en-us" />
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
This means that the URL in question has hreflang annotations where at least one of the alternate hreflang URLs does not reciprocate.
If the URL is https://example.com/us/ … there will be an issue if the URL has an outgoing hreflang.
<link rel="alternate" href="https://example.com/de/" hreflang="de-de" />
<link rel="alternate" href="https://example.com/es/" hreflang="es-es" />
Whereas the URL https://example.com/de/ would have the following hreflang but no reciprocal link back to the /us/ page.
<link rel="alternate" href="https://example.com/es/" hreflang="es-es" />
More on this issue: Empty Hreflang URL
This means that the URL in question has at least one outgoing hreflang annotation which is redirected to another URL.
With the example URL of https://example.com/page-1/ … there will be an issue if it included an hreflang annotation:
<link rel="alternate" href="https://example.com/us/page-a/" hreflang="en-us" />
This means that the URL in question has one or more outgoing hreflang annotations that are configured incorrectly.
If the URL is https://example.com/us/ … there will be an issue if if it had misconfigured or unsupported hreflang:
<link rel="alternate" href=" " hreflang="en-us" />
Another example:
<a href="https://example.com/de/" hreflang="de-de"></a>
More on this issue: Invalid order of Hreflang values
More on this issue: Underscore Instead of Dash in Hreflang
More on this issue: Hreflang Not Present