What Is Hreflang?

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:

 

Setting the Hreflang Tag

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.

Methods to Implement Hreflang Tags

There are three different ways that you can tell a search engine about multiple language and location versions of a page.

1. HTML Tags

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.


2. HTTP Header

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"

3. Sitemap

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:

  • www.example.com/english/page.html — targeted at English speakers.
  • www.example.com/deutsch/page.html — targeted at German speakers.
  • www.example.com/schweiz-deutsch/page.html — targeted at German speakers in Switzerland.

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> 

General Targeting With X-Default

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/" />

Guidelines for All Methods

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.

 

Common Hreflang Tag Issues

There are many potential issues that can arise with the hreflang tag. The below list is common issues found with hreflang.

For a full breakdown of common hreflang mistakes and how to be proactive about issues, read our helpful article: 12 Common Hreflang Mistakes and How to Prevent Them

 

1. Failing to include return links.

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.

2. Incorrect language codes. 

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 

3. Invalid incoming hreflang annotations.

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 

4. Invalid outgoing hreflang annotations.

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 

5. Outgoing hreflang annotations to noindex URLs.

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.

6. Noindex URL has incoming hreflang.

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.

7. Has outgoing hreflang annotations to broken URLs.

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 

8. Has outgoing hreflang annotations to canonicalized URLs.

This means that the URL in question has at least one outgoing hreflang annotation which is canonicalized to another URL.

9. Canonicalized URL has incoming hreflang. 

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 

10. Has outgoing hreflang annotations to disallowed URLs. 

This means that the URL in question has at least one outgoing hreflang annotation URL that is disallowed in robots.txt.

11. Has conflicting incoming hreflang annotations.

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 

12. Has conflicting outgoing hreflang annotations. 

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 

13. Has multiple self-referencing hreflang annotations. 

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 

14. Has outgoing hreflang annotation to multiple URLs.

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 

15. Has outgoing hreflang annotations using relative URLs.

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 

16. Mismatched hreflang and HTML lang declarations. 

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" />

17. Missing reciprocal hreflang. 

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 

18. Has outgoing hreflang annotations to redirecting URLs.

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" />

19. Has unsupported or misconfigured hreflang. 

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 

Resources

For further reading on hreflang, reference the following: