Setting hreflang and x-default on multilingual site (with Hugo)

Setting a hreflang meta tag on your multilingual website shall be as simple as a piece of cake. Just put the relevant meta tag on your website, refer to the translated version and on translated version refer back to the original one.

Looks as simple as that. End of story? Wrong!

As simple as it sounds, not always, in practice it is like that. If you operating a website in multiple languages, but not all the content is served with its translated counterpart, setting and using a hreflang tag across the website is a bit of a challenge. If you add to that the correct use of the x-default meta tag, this becomes even more of a challenge.

Once you thinking how to implement this correctly, more questions arise and searching the internet will give you answers that don’t match to each other.

Even Google in their Google Search Central documentation has its post titled Tell Google about localized versions of your page which does not clarify some scenarios.

Luckily, on the 8th of March 2023, a new post appears titled How x-default can help you which changes your perspective on how you shall look into the implementation of a hreflang and x-default meta tags.

It’s all about the conversions and not international targeting as many think. Even Google pushed back from this.

This post finally answers some of my questions.

The main approach is to change your way of thinking about a hreflang and the x-default tag.

Your goal is very likely to convert in some way the users that land on your pages.

(…) if you only published the essay in German, it’s unlikely that non-german speakers would convert on that page, so you might want to send them somewhere else where they might actually convert in some other way (…)

Think about the above when reading further.


My main website address (/) refers to the Polish version. If you head to /en/ you land on the English version.

Some posts are translated and nicely linked with each other through the flag in the right-top corner. If the post is available in English and you are on the Polish part you can click the English flag and you reading in English.

For this type of page there is a hreflang meta tag for Polish and English on both of the posts self-referencing each other.

If is not, I am offering auto-translation using Google Translator, which is not as bad as it was years ago.

The problem is that I am not translating everything into the English language if I am writing in Polish. Same, if I am starting to write a post in English (like this one), not always I will decide to translate it back to Polish. Sometimes it’s simply pointless and consumes unnecessarily my time without any gains for my readers.

Sometimes the decision to translate or not is dictated by the context of the post. Sometimes something written in English will make sense for an English speaker but will not make sense at all for a Polish speaker, especially if he is reading it from Poland (with a Polish approach), and not like me from the United Kingdom with an inherited British lifestyle.

You will probably get the point if I will try to translate a word or a meaning that got perfect sense in British English, but in Polish where it simply doesn’t exist. This will require you to give a full explanation of what you have on your mind when in English it’s just a single word (and vice versa).

The post How x-default can help you helps me understand how to implement a hreflang and how to use the x-default setting for conversion purposes.

I always struggle with x-default, as my website in Polish doesn’t contain all that is in English part.

I would not like to suggest for non-(default)-English, and non-Polish speakers to go to the Polish site by default if they are set with a different (default) language, other than these two.

It is much easier for non-English and non-Polish speakers (let’s say French speakers with French set as their default language in the operating system) to land on the English part of the website rather than Polish by default. It’s more likely that they will understand English rather than Polish.

But also I would like some people to know that if I write something in Polish and it’s not available in English, they can use the translate button on the right-top corner to get it translate, rather than simply close the page that they don’t understand.

This is where the right setting and the right understanding of how to utilise the x-default meta tag come in handy with the conversion on our minds.


Starting from the basic approach when both pages are translated (like my About Me page), the halfling in the head will look like below.

On Polish page about me (/o/)

<html lang=pl-pl xml:lang=pl-pl>
...
<link rel=alternate hreflang=pl href=https://dariusz.wieckiewicz.org/o/>
<link rel=alternate hreflang=en href=https://dariusz.wieckiewicz.org/en/about/>

On same page in English (/en/about/)

<html lang=en-gb xml:lang=en-gb>
...
<link rel=alternate hreflang=en href=https://dariusz.wieckiewicz.org/en/about/>
<link rel=alternate hreflang=pl href=https://dariusz.wieckiewicz.org/o/>

Thats straight forward approach when both ends are translated.

In Hugo this will be implemented in the <head> with the following code.

<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
{{ range .Translations }}
	<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
{{ end }}

But what if I will write a post that is only in English?

I can add a condition, where there is no translation the whole hreflang will be omitted.

{{ if .IsTranslated }}
	{{ range .Translations }}
		<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
	{{ end }}
	<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
{{ end }}

This will result that some pages will have a hreflang and others not.

The conversion in mind approach is for such a thing, that if the result is in language, that, by default, the user will not understand, let’s suggest him something else that may interest him. In such a way it is more likely that he will explore something else in a language that he understands, rather than just leaving the website altogether.

In quoted suggestion I will still serve a hreflang tag, even if that page got only one language, and if the language is not the one that the user understands, will offer an alternative. The alternative site will be the language selection page on which I will explain available languages, the fact that not all pages will be translated by default and that users can still use pages that they don’t understand with the auto-translation option.

This will look as below example:

<html lang=en-gb xml:lang=en-gb>
...
<link rel=alternate hreflang=en href=https://dariusz.wieckiewicz.org/en/minimal-google-analytics-4-snippet/>
<link rel=alternate href=https://dariusz.wieckiewicz.org/en/language-selector/ hreflang=x-default>

Or

<html lang=pl-pl xml:lang=pl-pl>
...
<link rel=alternate hreflang=pl href=https://dariusz.wieckiewicz.org/microsoft-mial-racje-nie-aktualizuj-do-windows-11/>
<link rel=alternate href=https://dariusz.wieckiewicz.org/en/language-selector/ hreflang=x-default>

In this way, each page will utilize a hreflang approach. If there is a translation, there will be additional language listed. As an alternative, there will be a reference to a dedicated page that can be understood by a majority of visitors from which they are more likely to convert further (read more).

For that, I will utilize the following code on my Hugo website:

<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
{{ range .Translations }}
	<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .RelPermalink }}">
{{ end }}
<link rel="alternate" href="{{ .Site.Params.langSelector | absURL }}" hreflang="x-default" />

In my Hugo config file (hugo.toml) I will specify an address for the language selection page

[params]
	langSelector = "/en/language-selector/"

In the frontmatter of the markdown file where I will put my content, I will present the URL.

---
url: '/en/language-selector/'
---

This will work as explained in Google’s latest blog post.

However if you only published the essay in German, it’s unlikely that non-german speakers would convert on that page, so you might want to send them somewhere else where they might actually convert in some other way. You can express this with hreflang=“x-default”

Hope that clarifies something for people in a similar situation to mine, where not all posts are translated equally.


There are some tools available on the internet that will tell you if you correctly implemented hreflang. Others will tell you something different. That’s because the approach described above is not a typical, most commonly known way of implementation yet still correct.

Gary Illyes, Analyst at Google said this on his LinkedIn profile:

While a hreflang x-default value was implemented to help with very specific needs, incidentally it can also help with feeding Googlebot URLs that the poor thing otherwise might not see. This is not a new thing, but I think it’s pretty cool that it has “hidden” use cases.

If you want to learn more, head to the documentation on how to Tell Google about localized versions of your page.

Comments
Categories