Setting up My English Blog By Hugo

A few days ago, I came across something quite infuriating on Twitter: A blog post written by a user I follow was translated into English and reposted on Medium, garnering a significant number of views, as well as thoughtful and heartfelt comments from users. I've often seen articles from English-speaking communities translated into Chinese and repurposed as content farms, but this was the first time I'd seen the reverse—Chinese content translated into English for reposting. It was even more frustrating to see.

The blogger quickly reported the user who had reposted the translated article, and tried translating some of his own blog posts into English with the help of ChatGPT and posting them on Reddit. The response was very positive, with one post even topping the channel. As someone whose work is always related to internationalization, I suddenly realized that in addition to keeping up with the trend of going global for work, personal output—like writing and coding—could also be "exported" to English-speaking communities abroad. Especially now, with the powerful ChatGPT, almost anyone can translate their content into decent English.

So, I translated some of my blog posts into English and, using Hugo's multilingual capabilities, created an English version of my blog.

How to Set Up Multilingual Support in Hugo?

Most Hugo themes come with multilingual configuration options. Here are the main things to consider when configuring multilingual support in a blog:

  1. Blog title
  2. Navigation bar title
  3. Text display of comment components
  4. Content of the "About" page
  5. Blog content
  6. RSS subscription
  7. Web page footer text

Language Settings

Hugo supports multiple languages. Detailed settings can be found in the Multilingual mode documentation. To support English, the main thing we need to do is add language configuration. Here, after adding the new 'en' language, we also need to add the previous default 'zh' language configuration.

Different language articles are placed in different directories through the contentDir setting. I see that the format is usually set as content/lang, but since I've already occupied content with Chinese, I just set an /en path for English. Subsequent English blog posts are placed under content/en/posts/.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[languages]
    [languages.zh]
        contentDir = 'content'
        disabled = false
        languageCode = 'zh-CN'
        languageDirection = 'ltr'
        languageName = 'Simplified Chinese'
        weight = 1
    [languages.en]
        contentDir = 'content_en'
        disabled = false
        languageCode = 'en-US'
        languageDirection = 'ltr'
        languageName = 'English'
        title = "YeungYeah's Blog"
        description = "Record the YeungYeah's thoughts and actions."
        siteDescription = "Record the YeungYeah's thoughts and actions."
        weight = 2

You can override the title and description of the blog website under multiple languages through the configuration in languages.

Blog Title / Navigation Bar Title

The blog title can be overridden in the above language configuration, setting it to an English title. For the navigation bar, you can directly copy the original navigation bar settings and modify the name to English. Note that you need to add a new link to the navigation bar for switching between Chinese and English on the site. The link addition is simple: English redirects to /, and Chinese redirects to /en.

 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
[[languages.en.menu.main]]
    url = "/en/posts/"
    name = "Posts"
    weight = 2
    pre = "internal"
    post = "archive"

[[languages.en.menu.main]]
    url = "/en/tags/"
    name = "Tags"
    weight = 4
    pre = "internal"
    post = "tags"

[[languages.en.menu.main]]
    url = "/en/about/"
    name = "About"
    weight = 1
    pre = "internal"
    post = "user-circle"
[[languages.en.menu.main]]
    url = "https://www.travellings.cn/go.html"
    name = "Travel"
    weight = 5
    post = "subway"
[[languages.en.menu.main]]
    weight = 7
    identifier = "theme-switcher"
[[languages.en.menu.main]]
    url = "/"
    name = "中文"
    weight = 6
    pre = "internal"
    post = "user-circle"

Comment Component

My blog uses Waline as the comment component. Waline inherently supports multiple languages, you just need to set the lang attribute when initializing the Waline component. The Hugo theme I originally used only provided parameters to set the language, but did not allow for switching the language of the comment component based on Hugo's multilingual settings. So I found the corresponding place and added a judgment: if the current page link contains /en/, it means that it is in English blog state.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const lang = {{ if in page.RelPermalink "/en/" }} 'en' {{ else }} {{ .Site.Params.walineLang }} {{ end }};
Waline.init({
    el: '#wcomments',
        placeholder: '{{ .Site.Params.walinePlaceholder }}',
        serverURL: '{{ .Site.Params.walineServerURL }}',
        pageview: {{ .Site.Params.walineVisitor }},
        comment: {{ .Site.Params.walineVisitor }},
        meta: {{ .Site.Params.walineMeta }},
        lang: lang,
        requiredMeta: {{ .Site.Params.walineRequiredMeta }},
        pageSize: {{ .Site.Params.walinePageSize }},
        dark: 'html[data-theme="dark"]',
})

"About" Page / Blog Content

For these text contents, just create new files under content/en/posts/. Here, I basically threw the Chinese content into ChatGPT4 for translation and then took it directly. In addition to the text content, the title and tags also need to be translated.

RSS Subscription

After configuring multilingual support, Hugo directly supports generating multilingual RSS feeds. However, my theme has an RSS subscription mark at the bottom of the page, and this configuration theme does not consider multiple languages, so I changed the theme configuration and wrote a custom rule: when the current page link contains /en/ and the configured id is rss, add an /en to its url.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{{ if .Site.Params.enableSocials }}
    {{ with .Site.Data.Socials }}
        <ul class="socials">
            {{- range sort .socials "weight" -}}
            {{ if and (in page.RelPermalink "/en/") (eq .id "rss") }}
                    <li class="socials-item">
                        <a href="/en{{ .url }}" title="{{ .title }}">
                            {{- partial "utils/icon.html" (dict "$" $ "name" .icon "class" "social-icon") -}}
                        </a>
                    </li>
                {{ else }}
                    <li class="socials-item">
                        <a href="{{ .url }}" target="_blank" rel="external noopener" title="{{ .title }}">
                            {{- partial "utils/icon.html" (dict "$" $ "name" .icon "class" "social-icon") -}}
                        </a>
                    </li>
                {{ end }}
            {{- end -}}
        </ul>
    {{ end }}
{{ end }}

The content of the footer is basically custom-added by myself, and there is basically no multilingual support. If you need to switch for the English blog, you need to add a condition judgment to the hardcoded customization.