How to Fix Hreflang Tag Issues: Best Practices & Implementation
Hreflang tags can often be overlooked and are sometimes implemented merely as a second thought. Because of this, sites that are trying to gain SERP real estate internationally can run into significant problems.
In this article, we’ll take a deep dive into hreflang issues: how to spot them and how to ensure correct implementation in order to increase targeted traffic from specific countries or users speaking a specific language.
What is Hreflang?
The hreflang is an HTML attribute meant to tell search engines the relationship between different versions of a page that are targeting specific languages and/or locations.
This attribute is placed in a link tag in the head section of the HTML document and defines the language and country the page is targeting. Here’s how it looks when implemented:
<link rel=”alternate” href=”https://example.com” hreflang=”en-us” />
Hreflang Attribute and SEO
Understanding how the hreflang attribute works is crucial for international SEO success. Whether you’re running an eCommerce or a physical business with multiple stores in different countries, it’s important to localize your pages for your audience.
Let’s use the Grand Hotel San Marino as an example. They receive tourists from all over the EU, so they’ve created Italian, English, German and French versions of their website.
If it were just about language, the team could simply use the lang attribute inside an html tag to tell the browser and search engines what the designated language is for the page (although most search engines don’t use this tag anymore for language detection).
However, it doesn’t tell search engines that there are other versions of the page, nor does it define the relationship between those versions and the current one. Because of this, search engines can flag other versions as duplicate content, or ignore them altogether, which can prevent them from getting indexed.
Note: Google will only flag pages as duplicates if they’re in the same language, but not translated versions. In other words, if your page has a different English version for the US, UK, and Canada, you can run into duplicate content issues. However, having French, English, and Italian versions won’t cause the same problem.
We also want users to find the correct version of the site depending on their language and location. So French-speaking users can find the French version of URLs when searching on Google or Bing.
Hubspot has a great example for this:
“If a user searches for HubSpot.com from Germany, an hreflang tag is responsible for changing the link available in the search engines. However, when someone lands on HubSpot.com in Germany, a lang tag changes the language on the page itself.”
So, to put it simply, hreflang tags allow us to control how search engines manage our multilingual websites and to ensure our users are always getting the version they need.
How to Implement Hreflang Tags
Now that we understand the importance of the hreflang tag for our SEO goals, we also need to be able to explain how to implement it to our developers.
Let’s explore three main methods used to tell search engines about localized versions of our pages:
- HTML tags
- XML sitemaps
- HTTP headers
HTML Tags for Localization
The simplest – although most time-consuming – strategy is adding
<link> elements to the
<head> of your HTML site to tell search engines about the different variations of the page. You’re probably more familiar with this method as it’s easy to see in the HTML code when inspecting a website.
To get a clearer view of how this implementation works, we’re going back to the previous Grand Hotel example to inspect the site:
<link rel="alternate" href="https://www.grandhotel.sm/it/" hreflang="it"> <link rel="alternate" href="https://www.grandhotel.sm/en/" hreflang="en"> <link rel="alternate" href="https://www.grandhotel.sm/de/" hreflang="de"> <link rel="alternate" href="https://www.grandhotel.sm/fr/" hreflang="fr">
We can break this process into the following steps:
- Create a
<link>element for every variation of the page – including the original.
- Set rel equal to “alternate”
- Add the URL of the variation
- Set the hreflang attribute to the language and country
Also, keep in mind the following points:
- Like in the example above, you can add the language code alone but not the country code. If you only add a country code, search engines will ignore your tags.
- Make sure to self-reference the original page as part of the variation list, so Page A is also listed as part of the
- Every version of the page has to point to one another. If Page A points to Page B, but Page B doesn’t point to Page A, Google will read this as a fraudulent attempt.
Note from Google:
|Important: Put your <link> tags near the top of the <head> element. At minimum, the <link> tags must be inside a well-formed <head> section, or before any items that might cause the <head> to be closed prematurely, such as <p> or a tracking pixel. If in doubt, paste code from your rendered page into an HTML validator to ensure that the links are inside the <head> element.|
XML Sitemap for Hreflang Implementation
For large websites, or to handle more than 10 language and location variations, using the XML sitemap is a better alternative to using HTML tags, especially to avoid adding potentially hundreds of lines of code to your files.
Instead, we can create a list of hreflang child entries by specifying the main URL with
<loc></loc>, listing every variation as a child as
<xhtml:link/>, and following the same structure as in the HMTL tags.
Let’s imagine we want to implement this for Prerender; here’s how it would look like:
<url> <loc>https://prerender.io/react/</loc> <xhtml:link rel="alternate" hreflang="de" href="https://prerender.io/deutsch/react/"/> <xhtml:link rel="alternate" hreflang="de-ch" href="https://prerender.io/schweiz-deutsch/react/"/> <xhtml:link rel="alternate" hreflang="en" href="https://prerender.io/react/"/> </url>
We can break this process into the following steps:
- Create a
<url>element for each URL
- Inside the
<url>element, add a
<loc>element to specify the URL
- Add a child element for each page variation including itself, and it has to specify:
It’s important that we add the full URL, including the protocol (http/https) and that we keep a consistent organization of the child elements. This is important for maintenance purposes, as it is easier to read and understand.
Using HTTP Headers for Localization
For non-HTML files like PDFs, we can “return an HTTP header with (our) page’s GET response to tell Google about all of the language and region variants of a page.”
Here’s an example from Google itself:
Link: <https://example.com/file.pdf>; rel="alternate"; hreflang="en", <https://de-ch.example.com/file.pdf>; rel="alternate"; hreflang="de-ch", <https://de.example.com/file.pdf>; rel="alternate"; hreflang="de"
As you can see when comparing methods, the only thing that changes is the way we deliver the information to search engines. The structure remains pretty much the same.
It really doesn’t matter which strategy you use in the end as long as you commit to it. There’s no need to combine different strategies.
Also, be aware that only a developer or someone with experience should mess with the HTTP headers, so using it for hreflang could be more time-consuming and difficult than the other two methods.
7 Most Common Hreflang Mistakes and Issues, and How to Solve Them
Although hreflang implementation is fairly straightforward, there’s still plenty of opportunity for mistakes and problems to arise.
Here’s a list of the seven most common issues we need to be aware of when doing a technical audit for international websites:
1. No Self-Referring Hreflang Tag
It’s easy to forget that you need to add the page itself on your hreflang map, but as stated by Google, “for each variation of the page, include a set of
<link> elements in the
<head> element, one link for each page variant including itself.” If the page isn’t mentioned in the hreflang map, then your code will be ignored. This rule also applies to sitemaps and HTTP headers.
As a best practice for HTML hreflang implementation, add your list after the canonical tag of the page like this:
<link rel="canonical" href="https://www.grandhotel.sm/it/"> <link rel="alternate" href="https://www.grandhotel.sm/it/" hreflang="it"> <link rel="alternate" href="https://www.grandhotel.sm/en/" hreflang="en"> <link rel="alternate" href="https://www.grandhotel.sm/de/" hreflang="de"> <link rel="alternate" href="https://www.grandhotel.sm/fr/" hreflang="fr">
Notice the canonical and “it” version is the same, making the page as part of the list.
2. Using the Canonical and Hreflang Tags Interchangeably
Talking about canonical tags. Something we’ve seen happening time and time again is pages using the canonical tag as if it were the self-referring link in the hreflang map or adding the hreflang attribute to the canonical tag itself. Both methods are wrong.
The canonical tag has a defined function and combining it with the hreflang attribute would result in errors:
<link rel="canonical" hreflang=”en” href="https://prerender.io/"> <link rel="alternate" hreflang="it" href="https://prerender.io/it/"> <link rel="alternate" hreflang="fr" href="https://prerender.io/fr/">
In here we are both misusing the canonical tag and leaving out the self-referring hreflang tag.
Note: There’s no need to canonicalize all versions to one. Canonical tags should be self-referring for both versions of the page.
3. Missing the Reciprocate / Return Links
A crucial step for any hreflang implementation is to make sure that Page A and Page B link to each other. If one of those pages doesn’t reciprocate the hreflang tag, Google will ignore your code to avoid misuse by 3rd parties trying to get their pages affiliated to yours arbitrarily.
Let’s say that Page A is our English version and Page B is our (hypothetical) French version, here’s how both annotations must look:
<link rel="canonical" href="https://prerender.io/"> <link rel="alternate" hreflang=”en” href="https://prerender.io/"> <link rel="alternate" hreflang="fr" href="https://prerender.io/fr/">
<link rel="canonical" href="https://prerender.io/fr/"> <link rel="alternate" hreflang=”en” href="https://prerender.io/"> <link rel="alternate" hreflang="fr" href="https://prerender.io/fr/">
4. Broken or Redirecting Hreflang URL
The function of the hreflang map is to tell search engines which URL should be indexed and displayed for users searching in specific languages or locations.
However, if the hreflang URL is redirected or broken (404), then the chain breaks, and search engines like Google will either decide to ignore your map or waste crawl budget requesting more pages.
For websites with thousands of pages like eCommerce or enterprise sites, this can become a huge crawl budget killer or create indexing loops.
We need to keep our hreflang map updated, always adding the destination URL into the
5. Hreflang URL Blocked by Robot.txt Files
Google needs to crawl every page version in order to find the return link and make sense of the hreflang map. In fact, John Muller has stated that “each language version has to be crawled and indexed at least twice for hreflang to work.”
When dealing with several versions, some webmasters tend to block “secondary” versions of pages from being crawled with a robot.txt directive, making it impossible for Google to access the page and invalidating the whole hreflang logic.
We’ve also seen noindex tags in the source code for international versions of the pages, which might cause search engines to ignore your code.
We say it might be ignored because, in some cases, users have seen their non-indexed international versions displayed on search results. Our guess is that Google can still understand the preferred version to be displayed by reading the hreflang tags. After all, it is still crawling those pages, just not getting them indexed.
6. Using Relative URLs instead of absolute URLs
Hreflang tags need to include the entire URL, including its protocol. By definition, they can’t handle relative URLs, which only include the path (everything after the domain).
As Content Kings puts it:
“Because relative URLs don’t include the entire URL structure, it is assumed that when linking a relative URL, it uses the same protocol, subdomain and domain as the page it’s on.”
However, they won’t work for hreflang tags and will get your entire hreflang map ignored. When mapping your hreflang links, make sure to add the absolute URL:
<url> <loc>https://prerender.io/react/</loc> <xhtml:link rel="alternate" hreflang="de" href="https://prerender.io/deutsch/react/"/> </url>
Instead of relative URLs:
<url> <loc>https://prerender.io/react/</loc> <xhtml:link rel="alternate" hreflang="de" href="/react/"/> </url>
7. Incorrect Language and/or Country Codes
Some issues we’ve encountered occur when webmasters try to use codes outside of the accepted formats. A clear example is trying to use “eu” to target the entire European continent or “uk” for the United Kingdoms.
To avoid confusion, always pull your code from the official language code lists recommended by Google.
How to Check for Hreflang Issues [Hreflang Audit Process]
Now that we understand what we’re looking for and how to implement correctly, it’s time to audit our websites to find – and solve – these issues.
The last thing we want is to manually check every page on our domain. Not only would that be a waste of time, it would also be extremely difficult. Instead, it’s better to use a technical auditing tool.
In our case, we’ll demonstrate a simple audit process using Screaming Frog (SC), but any other alternative should do something similar.
Note: You’ll need a paid license to use this feature.
1. Set Up Screaming Frog to Find Hreflang Annotation
The first thing we need to do is go to configuration > spider > crawl and select ‘crawl’ and ‘store’ hreflang. This allows Screaming Frog to crawl and report on any link found inside an hreflang annotation.
If the hreflang implementation was done in the sitemap, we’ll also need to enable “Crawl Linked XML Sitemaps” and add in the sitemap’s URL.
2. Crawl the Website
Go back to Screaming Frog and add the initial URL to start the crawl.
The hreflang tab will get populated in real-time.
3. Perform a Crawl Analysis
Although 12 out of 13 filters will be populated by now, to view the “unlinked hreflang URLs” report you’ll need to perform a crawl analysis. This is as simple as clicking a button:
4. View the Hreflang Filters and Bulk Export the Reports
Instead of going through all the data at once from the “All” view.
Screaming Frog allows 13 filters we can use to check for specific issues and information. For example, we can use the “missing self-reference” report to check for pages that don’t include themselves within the hreflang list.
Then, we can click on the URL and check the “URL Details” tab in the bottom panel to see more granular information on the error.
5. Bulk Export Reports for Further Analysis and Implementation
Now, all this information is great, but you’ll need it to be in a more useful format so you can plan and implement a strategy.
To export all the data within a report, go to reports > hreflang and pick the one you need.
Note: Although there’s a report for missing x-default tags, these are not always necessary but they are a best practice. So it’s not technically an error but something worth considering if you have a large audience that speaks a language outside of the targeted versions.
Hreflang Best Practices Checklist for SEO
Of course, the best way to deal with hreflang issues is to have the right implementation from the start. So if you’re working with a developer team on an internationalization project or you’re creating a new website from scratch that serves multiple languages and countries, here’s a checklist to help you stay in the clear:
|1. Pick one implementation method based on what works best for your business and skill level.||There’s no need to combine multiple methods as they won’t help you get the message across better. In fact, it could actually send confusing signals to Google if there are discrepancies between them.|
|2. Map out the languages and countries that you’ll actually need.||Don’t implement more countries and languages than you’ll actually need. There’s no point in having a UK, US, and Canada version if there is no difference between the services, products, or user experience you’ll provide.|
|3. Every variation has been included on all pages – including the self-referring link.||Do this in the mapping process before any implementation. It will be easier to see discrepancies.|
|4. Keep a consistent annotation order for the variations.||Because the order doesn’t matter, you can technically copy and paste the same format for all alternate variations, making it easier to implement and avoid mistakes.|
|5. The confirmation tag/return link is placed on every page.||If you follow step 4, it won’t be an issue.|
|6. Verify all language and country codes used.||Make it a habit to copy and paste these codes from Google’s recommended lists to avoid issues.|
|7. Verify that the language code matches the language on the page.|
|8. Make sure that only absolute URLs are being implemented.|
|9. Submit the changes to the desktop and mobile versions if they are different.||If not, it can create conflicting directives and get your code ignored by Google.|
|10. Test your hreflang configuration by running an audit or by using a tool like HreflangTest.com.|
Every version of your website is as important as the “original” site version, and the relationship between them is what provides users with a cohesive experience, no matter the language or country.
A solid Hreflang strategy will save you time and increase conversion rates by always providing the best result for your users. It’s a tiny, but critical, piece of the technical SEO puzzle, so it is worth the effort.
Keep this checklist close by and remember to always test and verify your process. Until next time!