Hexo Next 7.1 Bilingual Switching

2020 Update: This method has too many bugs and has been abandoned. It only applies to Next theme version 7.1. For a new method, please refer to Hexo Next 7.7 Bilingual Switching.


This post was translated from my Chinese blog post with the aid of ChatGpt.

For those who need an English version of their website, you’ll need to add a bilingual switching feature. Hexo has support for website internationalization, known as i18n. However, it has some limitations, as different language articles are mixed together, making it look messy. To address this, follow the steps below:

Plugin Installation

Install the Hexo internationalization plugin, i18n, by running the following command in your blog’s root directory:

1
npm install hexo-generator-i18n

Important Notes

Ensure that the i18n plugin is placed as the last entry in the dependencies section of your root directory’s package.json file. You will need to manually adjust this whenever you install a new plugin because every new plugin installation reorders the plugins alphabetically. The format should look like this, with no comma at the end of the last item:

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
"dependencies": {
"bookmark": "^0.2.3",
"clipboard": "^2.0.4",
"gitment": "0.0.3",
"hexo": "^3.8.0",
"hexo-asset-image": "0.0.3",
"hexo-deployer-git": "^1.0.0",
"hexo-generator-archive": "^0.1.5",
"hexo-generator-category": "^0.1.3",
"hexo-generator-index": "^0.2.1",
"hexo-generator-search": "^2.4.0",
"hexo-generator-sitemap": "^1.2.0",
"hexo-generator-tag": "^0.2.0",
"hexo-helper-live2d": "^3.1.1",
"hexo-prism-plugin": "^2.3.0",
"hexo-renderer-ejs": "^0.3.1",
"hexo-renderer-marked": "^0.3.2",
"hexo-renderer-stylus": "^0.3.3",
"hexo-server": "^0.3.3",
"hexo-symbols-count-time": "^0.4.4",
"hexo-wordcount": "^6.0.1",
"live2d-widget-model-tororo": "^1.0.5",
"live2d-widget-model-z16": "^1.0.5",
"hexo-generator-i18n": "0.0.7"
}

Modify Configuration File

Open the configuration file _config.yml in your blog’s root directory and make the following changes under the language section:

1
2
3
4
5
6
7
# language:
# - zh-CN
# - en
language: [zh-CN, en]
i18n:
type: [page, post]
generator: [index, archive, category, tag]

After making these changes, run hexo cl and hexo g to regenerate the public folder. At this point, a new directory /en will be generated to store the English site files. However, different language sites are still mixed together. To separate them properly, you need to add conditional generation rules for different language pages.

Add Generation Conditions

Open .\themes\next\layout\index.swig and add the following code at the end:

1
2
3
4
5
6
7
8
9
10
{% block content %}
<section id="posts" class="posts-expand">
{% for post in page.posts %}
{% if page.lang === post.lang %}
{{ post_template.render(post, true) }}
{% endif %}
{% endfor %}
</section>
{% include '_partials/pagination.swig' %}
{% endblock %}

Now, articles will only be generated if their language matches the page language exactly. Similarly, in files such as tag.swig, category.swig, archive.swig, etc., you can search for and set the post_template.render(post) condition to hide articles in other languages. Here’s an example:

tag

1
2
3
4
5
{% for post in page.posts %}
{% if page.lang === post.lang %}
{{ post_template.render(post) }}
{% endif %}
{% endfor %}

archive

1
2
3
{% if page.lang === post.lang %}
{{ post_template.render(post) }}
{% endif %}

category

1
2
3
4
5
{% for post in page.posts %}
{% if page.lang === post.lang %}
{{ post_template.render(post) }}
{% endif %}
{% endfor %}

Article Writing Format

In the blog post’s front matter, add lang: to differentiate between articles in different languages. For example, use lang: zh-CN for Chinese and lang: en for English, like this:

1
2
3
4
5
title: Hexo Bilingual Switching
date: 2019-04-09 17:12:53
lang: en
tags: [HEXO]
categories: Blog

Adding Language Switching Button

Open the Next theme configuration file .\themes\next\_config.yml and under Menu:, add switch_lang:, like this:

1
2
3
4
5
6
7
8
9
10
menu:
home: / || home
about: /about/ || user
tags: /tags/ || tags
categories: /categories/ || th
archives: /archives/ || archive
switch_lang: /en || language
#schedule: /schedule/ || calendar
#sitemap: /sitemap.xml || sitemap
#commonweal: /404/ || heartbeat

Open the zh-CN.yml and en.yml files under .\themes\next\languages, and add switch_lang: under menu: in both files.

zh-CN

1
2
3
4
5
6
7
8
9
10
11
menu:
home: 首页
archives: 归档
categories: 分类
tags: 标签
switch_lang: English
about: 关于
search: 搜索
schedule: 日程表
sitemap: 站点地图
commonweal: 公益 404

en

1
2
3
4
5
6
7
8
9
10
11
menu:
home: Home
archives: Archives
categories: Categories
tags: Tags
switch_lang: zh-CN
about: About
search: Search
schedule: Schedule
sitemap: Sitemap
commonweal: Commonweal 404

Adding Conditional Statements

At this point, the links are still one-way, meaning you can only navigate to the English page but cannot return to the Chinese page. Therefore, you need to add conditional statements.

In .\themes\next\layout_partials\head\head-unique.swig, add the following code to redirect the language switch button back to the Chinese page after loading the English page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
// Wait for the page to load first
var _prevOnload = window.onload;
window.onload = function() {
var switchLang = document.getElementsByClassName("menu-item menu-item-switch_lang")[0];
switchLang.onclick = function() {
var href = window.location.href;
var indexOfEn = href.toLowerCase().indexOf('/en');
if(indexOfEn !== -1) {
window.location.href = href.replace('/en/', '/');
}
else {
window.location.href = href.replace(/(^http[s]?:\/\/[a-z0-9.]*[:?0-9]*\/)(.*)/i, '$1en/$2');
}
if(typeof(_prevOnload) === 'function') {
_prevOnload();
}
return false;
}
}
</script>

As a JavaScript newbie, I struggled with this for a while. document.getElementsByClassName returns an array, and I kept getting errors while debugging. I had to add [0] at the end to get the class name.

Limitations

Although the above method can achieve language switching, when you click on tags, archives, categories, and other links on the English page, it will redirect you to the Chinese page. To switch to the corresponding Chinese page, you need to click the English switch button again on the redirected page. If there are better solutions, please feel free to leave comments in the comment section.

Reference: wm4n