Hugo i18n Automatic Language Redirection

      β˜• 3 min read
🏷️
  • #hugo
  • #i18n
  • #multilingual
  • 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:

    1. create my own layouts/alias.html;
    2. use javascript to detect user’s language preference and redirect;
    3. 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.

    Share on

    nanmu42
    WRITTEN BY
    nanmu42
    To build beautiful things beautifully.

    What's on this Page