Hugo has really neat support for i18n. Unfortunately, it does not provide a straitforward way to redirect your visitors automatically according to their web browser language preferences. The good news is that Hugo authors leave a window open for solving this problem.
The Problem
My site is running on two languages: English and Chinese. I have defaultContentLanguageInSubdir
set to true
and defaultContentLanguage
set to en
. When visitors came to root /
of my site, their web browsers got following response:
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html>
<html>
<head>
<title>https://nanmu.me/en</title>
<link rel="canonical" href="https://nanmu.me/en"/>
<meta name="robots" content="noindex">
<meta charset="utf-8" />
<meta http-equiv="refresh" content="0; url=https://nanmu.me/en" />
</head>
</html>
|
Browsers see http-equiv="refresh"
meta and then redirect. Search engines see noindex
meta and does not index this page.
However, redirecting every visitor to English version blindly is not very user-friendly, how to redirect by user’s language preference?
The Open Window
After digging into doc and code, I found one can actually customize these redirection pages by creating an alias.html
template in the layouts folder of your site (i.e., layouts/alias.html
).
For example, here is the default _internal/alias.html
template, looking familiar, right?
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html>
<html>
<head>
<title>{{ .Permalink }}</title>
<link rel="canonical" href="{{ .Permalink }}"/>
<meta name="robots" content="noindex">
<meta charset="utf-8" />
<meta http-equiv="refresh" content="0; url={{ .Permalink }}" />
</head>
</html>
|
Solution
The road is straight now:
- create my own
layouts/alias.html
; - use javascript to detect user’s language preference and redirect;
- visitors are happier! :D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
<!DOCTYPE html>
<html>
<head>
<title>{{ .Permalink }}</title>
<link rel="canonical" href="{{ .Permalink }}"/>
<meta name="robots" content="noindex">
<meta charset="utf-8"/>
<noscript>
<meta http-equiv="refresh" content="0; url={{ .Permalink }}"/>
</noscript>
<script>
;(function () {
// Only do i18n at root,
// otherwise, redirect immediately
if (window.location.pathname !== '/') {
window.location.replace('{{ .Permalink }}')
return
}
var getFirstBrowserLanguage = function () {
var nav = window.navigator,
browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
i,
language
if (Array.isArray(nav.languages)) {
for (i = 0; i < nav.languages.length; i++) {
language = nav.languages[i]
if (language && language.length) {
return language
}
}
}
// support for other well known properties in browsers
for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
language = nav[browserLanguagePropertyKeys[i]]
if (language && language.length) {
return language
}
}
return 'en'
}
var preferLang = getFirstBrowserLanguage()
if (preferLang.indexOf('zh') !== -1) {
// visitor prefers Chinese
window.location.replace('/zh-cn/')
} else {
// fallback to English
window.location.replace('/en/')
}
})()
</script>
</head>
<body>
<h1>Rerouting</h1>
<p>You should be rerouted in a jiff, if not, <a href="{{ .Permalink }}">click here</a>.</p>
</body>
</html>
|
Credits
Thanks to Thomas Enzinger for getFirstBrowserLanguage()
in the Javascript above.