Skip to main content

Have you ever wondered if you can implement hreflang with Google Tag Manager? Yes, you can! Or are you just looking for the easiest way to implement hreflang on your website if you’re not a developer? Well, here it is. In this article, we show you how to implement hreflang using Google Tag Manager in three easy (well, kind of easy) steps.

All you need is a website with more than one country or language version that have links pointing to each other and an implementation of Google Tag Manager on your website. So here we go!

The challenge: Every group of language versions gets its own set of hreflang annotations

If you are reading this post, I assume that you already understand the basic concept of hreflang: Every page on your website needs hreflang annotations pointing to all of its different country and language versions, including one pointing to the URL itself.

Here’s an example.

Our blog page exists in English (https://www.searchviu.com/en/blog/) and German (https://www.searchviu.com/de/searchviu-blog/), so both versions need
the following hreflang annotations (pointing to themselves and to each other):

<link rel="alternate" href="https://www.searchviu.com/en/blog/" hreflang="en">
<link rel="alternate" href="https://www.searchviu.com/de/searchviu-blog/" hreflang="de">

The same goes for the two versions of our home page (https://www.searchviu.com/en/ and https://www.searchviu.com/de/):

<link rel="alternate" href="https://www.searchviu.com/en/" hreflang="en">
<link rel="alternate" href="https://www.searchviu.com/de/" hreflang="de">

And so on, for every pair of English and German pages…

Important note: The solution presented in this post works for websites with any number of country/language versions. In the case described here, there are only two versions, German and English, but we also explain what you need to do if you have more versions than that.

As we don’t want to add hreflang annotations manually to every page on our website, but dynamically to all of our pages at once, we need a way to extract the URLs of all language and country versions for each set of pages.

If you find the next part a bit challenging, don’t despair. Just do it! The rest is a lot easier. And if anything remains unclear or if you have any questions, please don’t hesitate to get in touch. We’ll be happy to help!

Step 1: Extract the internal links to the different country and language versions from your website using “DOM Element” GTM variables.

The URLs of the other language or country versions of a page can normally be found in some kind of language or country switcher on the page that contains links to the other versions. This is where we can extract the URLs we need for the hreflang annotations.

Google Tag Manager has a variable type called “DOM Element”, that allows us to extract information from the HTML code of a page. I will now show you exactly how to create a variable of this type for every language and country version of your website.

In Google Tag Manager, go to “Variables”, scroll down to “User-Defined Variables” and click on “NEW”. In the new dialogue that opens, click on the variable configuration and select the variable type “DOM Element”. The variable has two selection types, “ID” and “CSS selector”. In this case, we will need the one that is called “CSS selector”. You should now see this:

DOM element GTM variable with CSS selector option enabled

Let’s start filling the empty fields now. The variable name at the top is a no-brainer. Give it the name of the country or language version you want to start with (remember, we are extracting links to country or language versions and creating one variable for each of them). In this case, I want to start with the German version of searchVIU, so I call the variable “Link to German version”.

The “Element Selector” part is probably the trickiest part of this whole instruction. I am going to show you the easiest way, not the most sophisticated way, to fill it. If you find some time to learn how CSS selectors work, you will find nicer ways of filling this field, but for now, the basic variant will do.

The easiest way to identify the CSS selector of a link to another language or country version on one of your pages is by right-clicking on the link in Chrome and selecting “Inspect”. Chrome’s developer tools will open with the HTML code of the link already highlighted. On the English blog page on the searchVIU website (https://www.searchviu.com/en/blog/), after doing the above for the link to the German version, we see this:

HTML code of link to German website version highlighted in Chrome's developer tools

Now, in order to get the CSS selector of this link, we just right-click on the highlighted bit of code in Chrome’s developer code and select “Copy > Copy selector”. We then paste this value (“#menu-item-443-de > a” in our case) into the field “Element Selector” back in the variable we are creating in Google Tag Manager.

Now we have the field “Attribute Name” left. If we left this blank, the variable would give back the link text, “DE” in this case. But we want the URL, so we fill the field with “href”, the name of the attribute of the <a> element that has the URL as its value.

Here’s how this should look for you now, except for the value in the field “Element Selector”, which you will need to replace with the individual value that works for your website:

Configured variable for link to other language version

In our case, we need to do this once for links pointing to the German versions of our pages, and once for links pointing to the English versions. If you have more language or country versions than we have, you can repeat this process for every one of them. In Chrome, right-click on a link to the language version, choose “Inspect”, right-click on the highlighted bit of code in Chrome’s developer tools, select “Copy > Copy selector” and paste the copied value into the “Element Selector” field of a new user-defined variable in GTM. Fill the “Attribute” field with “href” and give the variable the name of the country or language version the link points to. Repeat for each country or language version on your website.

Before moving on, you can check if your variables are working by activating GTM’s preview mode, visiting your pages, and selecting the “Variables” tab in the GTM debugging overlay. You should see the correct values for the variables of all other language/country versions of the page you are on (not for the page itself). For searchVIU’s home page, it looks like this:

Checking variables in GTM

Step 2: Create a GTM tag with a script that generates hreflang annotations for each language version.

Congratulations! If you’ve made it up to here, you’ve managed the hardest part of this implementation. Now that we’ve got the GTM variables for the URLs of the different language/country versions set up, let’s add the hreflang annotations to our pages!

Here’s the script we will need for the hreflang implementation on the English version of all pages on our website, with a quick explanation of each line below.

<script>
var link_en = document.createElement('link');
link_en.rel = 'alternate';
link_en.href = '{{Page URL}}';
link_en.hreflang = 'en';
jQuery('head').append(link_en);
var link_de = document.createElement('link');
link_de.rel = 'alternate';
link_de.href = '{{Link to German version}}';
link_de.hreflang = 'de';
jQuery('head').append(link_de);
</script>

The first line creates a <link> HTML element:
<link>

The second line adds a rel attribute with the value “alternate” to the link element.
<link rel="alternate">

The third line adds an “href” attribute with the value of the current page to the link element. {{Page URL}} is a built-in variable in GTM and always gives back the full URL of the current page. When we implement this script on the English blog page, we get the following result:
<link rel="alternate" href="https://www.searchviu.com/en/blog/">

The fourth line adds an hreflang attribute with the value “en” to the link element. The hreflang value can be hard-coded here, as we will be adding this script to the English version of our website only, and a separate script to each other language version:
<link rel="alternate" href="https://www.searchviu.com/en/blog/" hreflang="en">

The fifth line bangs this into the header of the post-DOM HTML (aka rendered HTML) of your page, once the script is executed in Google Tag Manager.

So, with the first five lines of this script, we have generated the self-referencing hreflang annotations for the English version of the blog page. As the page URL is added dynamically with the help of a GTM variable, this exact same script will work for all English URLs on the entire website.

Let’s now have a look at the next five lines of the script. They are very similar to the first five lines, with the slight difference that they don’t generate a self-referencing hreflang annotation, but the one that references the German version of the English blog page, using the custom variable we set up in the previous step:

<link rel="alternate" href="https://www.searchviu.com/de/searchviu-blog/" hreflang="de">

Again, as the script uses the variable we set up in step 1 for extracting the URL to the German version from the page, this exact script will work on all pages of the English website version.

You can repeat the last five lines for every additional language or country version your website might have, so that the English pages don’t just point to one other version, like in our case, but to all country/language versions you might have.

Next, we add the above script to a “Custom HTML” tag in Google Tag Manager and set the triggering options so that it executes on all English pages:

hreflang script for English pages

We will need a tag of this kind to execute on all pages of each language version, so next, we create the same script for all German pages, with the variables and hreflang values replaced accordingly:

hreflang script for German pages

You can repeat this step for every single one of your language/country versions.

Note: If you have lots of language/country versions, and if you’re a real GTM ninja, you might want to work with variables for the hreflang values too.

That’s it, basically! It was easier than you thought it would be, wasn’t it?

Let’s have a look at one more step you might want to perform, if you’re still in the mood…

Step 3 (optional): Add an hreflang=”x-default” version.

If you’re familiar with how hreflang works, you probably know what “x-default” is (if not, check here). You might not need to assign the value “x-default” at all within your hreflang implementation, but if you do, this last step is for you.

On searchviu.com, we do need an “x-default” value pointing from the two versions of our home page to our root URL (https://www.searchviu.com/), as this root URL redirects users to either one of the two language versions of our home page, based on their browser language, and therefore represents a classic case for the use of “x-default”.

The implementation is dead simple, and I’m sure you’ll be able to figure it out yourself after doing all of that complicated stuff above, but here’s a screenshot:

hreflang x-default in GTM

If like us, you need an hreflang annotation with the value “x-default” pointing to your root URL from all home page versions, just make sure this tag executes on all versions of your home page and you’re done.

In a different scenario, you might want to assign the value “x-default” to all pages of a language version that you have already assigned a language or language/country value to. In this case, you’ll have to fire the above script with the variable {{Page URL}} for the href value on all pages of that language/country version. In addition to that, you’ll have to fire the same script with the variable from step 1 that contains the URL of that language version for the href value on all pages of all other language versions. Easy as cheese, isn’t it?

Ok, cool, but does this actually work?

Yes, it does! As we already demonstrated in a previous article, Google relies on the rendered HTML for interpreting hreflang annotations and ignores the HTML source document. This means that there is absolutely no problem with implementing hreflang in Google Tag Manager and that Google processes it just fine.

One problem that hreflang annotations can solve is when Google is not able to rank the right URL versions of international or multilingual websites for the right users without further help. Before we implemented hreflang with this method on our website, the German home page and the root URL (with an English snippet) were ranking in google.de for our brand searches:

About a week after the implementation of hreflang, this changed and Google only showed the German version in google.de. Thanks to hreflang and the assignment of the value “x-default” to the root URL, Google understood the multilingual structure of our website better. Here’s what it looks like now:

searchVIU results after hreflang implementation

So, as you see, this method works just fine.

Any questions? Please let me know!

I really hope you liked this article and that it helped you implement hreflang with Google Tag Manager yourself. If anything remains unclear or if you run into any problems, please don’t hesitate to give me a shout. I’m always happy to help! Also, if you have anything to add to what has been written here, please share your experience with us.

Eoghan Henn

Author Eoghan Henn

Eoghan Henn is responsible for searchVIU's marketing. Before joining searchVIU, he worked as an SEO consultant for 6 years and built a reputation as a blogger and conference speaker.

More posts by Eoghan Henn

Join the discussion 23 Comments

  • tizzy says:

    GTM can help implement hreflang tags on a massive website with thousands of URLs effortlessly

    but my question is:

    Can other search engines like Bing, duckduckgo, yandex etc process hreflang tags implement with Google’s tag manager?
    without issues – and display the correct language versions in their serps?

  • Sören says:

    Thanks for this very interesting article. It is very useful! I’ve tried to follow the instruction, however pictures are not loading, so I’m not sure if I did correct. Is it possible to publish the pictures in this blog post?

    • Eoghan Henn says:

      Hi Sören,

      Thank you for your comment and for pointing out the problem with the images. They are working now, so it might have been a temporary problem. If you have any further questions, please just let me know.

  • I have a single language site. And it gives me hreflang issues. How to resolve plz

    • Eoghan Henn says:

      On a single language site, as long as you don’t have several country versions in the same language, you don’t need hreflang. If a tool is highlighting hreflang issues on a website with just one country/language version, you can probably ignore them.

  • Ben says:

    Thanks for this helpful post. I’m wondering if you have any ideas on that could help me take this to another level, assuming I haven’t missed something:

    An ecommerce store has some stock in both GB and DE – these pages need mutual hreflang tags. However, other stock is only available in one or the other and these pages don’t need hreflang. Crucially, this isn’t fixed – it can change as stock becomes available or sells out, which happens a lot. Is there a way to implement this with a trigger that checks that both pages exist first, then only adds hreflang tags to those that do?

    Thanks in advance for any ideas!

    • Eoghan Henn says:

      Hi Ben,

      Thank you very much for your interesting question! Your idea can work if there’s a country switcher link on each product page that links to the equivalent in the other country version (which you need anyhow for this solution to work). You could set up a trigger that checks if the country switcher is available and links to the correct URL and then only fire the tag if the conditions are met. It all depends on how the page is built exactly.

      I’d be happy to have a look if you send me some more info!

  • Matt Tutt says:

    Hey Eoghan,

    I realise a bit of time has now passed since you wrote this guide, but have you noticed that it no longer works, or is it still a good suggestion for those situations where site access is an issue / hreflang tags aren’t supported?

    I’m looking at using this for an ecommerce client that has a situation like the above (CMS doesn’t support hreflang tags) and GTM access is available. It’s a weird setup though: the client has 1 well established site in Brazil, with just Portuguese language in use. They recently launched a new site in the US, in English only. However the domain name (brand name) is different across both sites, and also (more importantly) the content isn’t translated like-for-like across each page – they have a different homepage layout and different navigation menu/categorisation of products.

    I’m thinking of manually creating hreflang tags for the pages that do exist on the same topics across both sites, so the homepage, and a few of the product category pages. A custom hreflang tag (via a HTML tag in GTM) and a custom trigger, set to fire when page URL equals “https://www.website.com/”.
    This is a more basic and manual approach to your suggestion above – but *in theory* should what I’ve described work? Sorry if that is wildly different to what you’ve described in this article, or is a bit cheeky of me to be asking here!…

    • Eoghan Henn says:

      Hi Matt!

      Thank you very much for your interesting question. Yes, as far as I know, this should still work.

      If you have any further questions, please just let me know.

  • Rishi says:

    Hi Eoghan,

    This is very interesting thanks..
    Can we do it for separate domains altogether?
    For ex – I have xyz.com/blog/1-2-3 in English and other abc.com/blog/1-2-3 in German Can I use tag manager to add lang tags for both the domains.

    Highly appreciate it.

    • Eoghan Henn says:

      Hi Rishi,

      Yes, this should work across domains without a problem, as long as there are links between the versions, so that you can extract the URLs of the other versions form each page.

  • Hi Eoghan,

    Thanks for this tutorial! I’ve implemented in the GTM for a customer and published. When I use a tool however to check the rendered html I see the variable isn’t placed in the but only after. Will this lead to any problems you think and do you perhaps have a solution?

    Thank you in advance!

    Best regards,
    Chantal Klerks

    • Eoghan Henn says:

      Hi Chantal,

      Thank you very much for your interesting question. Which tool did you use to check the rendered HTML? Your description sounds like what might be happening here is that the head is broken due to certain elements that don’t belong there (more details about this issue here: https://ohgm.co.uk/breaking-head-quietly/). The method described above should always place the hreflang annotations at the end of the head and I’m afraid they won’t be recognised if they end up outside of the head.

      If you send me the URL of the page you’re working on, I’ll be happy to have a closer look.

      Best regards,

      Eoghan

  • Jon says:

    Hello Eoghan Henn,

    Thank you very much for the tutorial.

    I have the impression that I can’t get the right css selector for each language. Every time I check the trial version of google tag manager I get an error.

    I would like to know if you can help me.

  • Sylvain says:

    I cant’t find what i’m doing wrong ?

    I don’t have multilinguage plugin install, i just mage a custom link in the menu

    Do i need to have a multilingual plugin installed ?

    Thank you for your post and hope reply.

    Sylvain

    • Eoghan Henn says:

      Hi Sylvain,

      It doesn’t matter how you implement the links from one language/country version to another. If you like, you can send me some more details via e-mail and I’ll be happy to have a look.

  • Stefan Reeves says:

    Hi Eoghan,

    Thank you so much for the help! I’ll definitely consider all options and see if there’s an available plugin as well 🙂

    Best regards,
    Stefan

  • Stefan Reeves says:

    Hi Eoghan,

    Thanks for all of this information! I’m wondering how much faster it is implementing hreflang through GTM versus the other methods? For example, I have a 1000 page e-commerce site that I’m translating into French and am not sure how big of a job this is. Thanks so much again!

    • Eoghan Henn says:

      Hi Stefan,

      If you have another option, I would always recommend checking that first, instead of implementing hreflang with GTM. The implementation of hreflang with Google Tag Manager is normally done fairly quickly and easily (especially if you’re used to working with GTM), but it then takes a while for Google to process the information, as the hreflang tags are only available in the rendered HTML. Google doesn’t render pages as regularly as it fetches their source HTML.

      It is always a safer solution to insert hreflang annotations directly into the source HTML. Your shop system might offer such an option, or there might be a plugin available.

      I hope this helps!

  • Victor says:

    Hi have followed the steps above but testing tools don’t recognise the tagging despite I can see it when I inspect the page.

    • Eoghan Henn says:

      Hi Victor,

      Thank you for your comment. Which testing tools are you using? I guess they can’t detect the hreflang tags because they only look at the HTML source code, not at the rendered HTML. When you implement hreflang with GTM, the tags will only show in the rendered HTML. You should be able to see the tags in the Google Search Console report “International targeting” after a couple of weeks. If you like, you can also send me the link to the website and I’ll have a look at it for you.

      I hope this helps!

      Best regards,

      Eoghan

      • Victor says:

        Hi Eoghan,

        Thanks for your quick reply!
        Yes, seems that the tools check the HTML source code, not the rendered HTML. In this case, I will wait a couple of weeks and check Search Console.

        Regards,
        Victor