loading...

Utilize Nginx to fulfill bilingualism for Hexo

chanvin profile image Chanvin Xiao Originally published at chanvinxiao.com ・4 min read

The bilingualism config process for Hexo is recorded In this article. Different language version is in the same application with common template, any webpage can be switched to another language's corresponding webpage, and for the access url whose language is not specific, automatic redirection will be proceed according to browser language

Fulfillment Rule

Address Difference

Chinese Home:

https://chanvinxiao.com/cn/blog/

English Home:

https://chanvinxiao.com/en/blog/

Switch between Languages

The following Chinese page as example

https://chanvinxiao.com/cn/blog/archives/2020/04/

Click English in the top right corner, the following webpage will be shown

https://chanvinxiao.com/en/blog/archives/2020/04/

Click 中文 in the top right corner in this webpage, the previous webpage will been shown

Automatic Redirection

The following address as example

https://chanvinxiao.com/blog/vuejs-tic-tac-toe/

If the browser prefer language is set to English, it will redirect to corresponding English version

https://chanvinxiao.com/en/blog/vuejs-tic-tac-toe/

If the browser prefer language is set to Chinese, it will redirect to corresponding Chinese version

https://chanvinxiao.com/cn/blog/vuejs-tic-tac-toe/

Hexo Setting

Add English Setting

Add _config-en.yml in the root directory

# Site
title: TITLE
subtitle: SUBTITLE
description: DESCRIPTION
keywords: KEYWORDS
language: en

# URL
url: https://chanvinxiao.com/en/blog
root: /en/blog/

# Directory
source_dir: source-en
public_dir: public-en
  • in the #Site associated setting, I change the original Chinese content to English, and the key point is to change language to en, thus the template will use english version
  • URL and root need to be set as individual address and directory to distinguish between chinese counterpart
  • Divide source and public directory from chinese, to ensure the Chinese or English version only show Chinese or English article respectively

Add Script

Add the following script in package.json

  "scripts": {
    ...
    "build:en": "hexo generate --config _config.yml,_config-en.yml",
    "clean:en": "hexo clean --config _config.yml,_config-en.yml",
    "server:en": "hexo server --config _config.yml,_config-en.yml"
  },
  • Add build, clear, and server script for English version, so the Chinese and English version is separated without interfering with each other
  • Utilize Custom Config, combine config _config.yml and _config-en.yml in the corresponding scripts
  • The combining config file _multiconfig.yml will be generated, which should be added to .gitignore

Nginx Config

Add the following config in corresponding server session in Nginx

  if ( $http_accept_language ~* ^en ) {
    rewrite ^(/blog.*) /en$1 redirect;
  }

  rewrite ^(/blog.*) /cn$1 redirect;

  location /cn/blog {
    alias /PATH/TO/BLOG/public;
    error_page 404 $scheme://$host/cn/blog;
  }

  location /en/blog {
    alias /PATH/TO/BLOG/public-en;
    error_page 404 $scheme://$host/en/blog;
  }
  • $http_accept_language is embedded variable set by Nginx's http module for request header Accept-Language, If prefer language of browser is English, the value will start with en, such as en-US,en;q=0.9
  • rewrite ^(/blog.*) /en$1 redirect; will add en for the address start with /blog, the flag of rewrite is set to redirect, which means 302 redirect, so does the following default cn
  • The above setting make redirect decision for address start with /blog (aka address without language), If the prefer language of browser is English, English site start with /en/blog will be redirected, or else Chinese version start with /cn/blog will be redirected
  • Because /cn/blog is matched with index.html in the public directory, not cn/blog/index.html, so here alias is used, not root
  • error_page is set for 404 handling, $scheme is http or https, which means webpage redirect, and will redirect to Chinese or English homepage

Webpage Switch

Use template landscape as example, add the following content before })(jQuery); in themes/landscape/source/js/script.js

  let language = {};
  language.now = location.pathname.match(/^\/en/) ? 'en' : 'cn';
  if('en' === language.now){
    language.label = '中文';
    language.href = location.pathname.replace(/^\/en/, '/cn');
  }else{
    language.label = 'English';
    language.href = location.pathname.replace(/^\/cn/, '/en');
  }
  $('#sub-nav').prepend(`<a class="main-nav-link" href="${language.href}">${language.label}</a>`)
  • Determine the language of current webpage according to the existence of /en in the beginning of webpage path
  • Add link menu to Chinese webpage in English webpage, and add English link in Chinese version
  • Directly change cn to en or en to cn in the address to get the corresponding webpage, if there is not corresponding webpage, the associated homepage will be redirected according to the above Nginx config
  • Utilize prepend of jQuery to add link to the sub menu, with the common class main-nav-link style

Summarize

In the fulfillment of blog bilingualism, the following technology is primarily used:

  • Custom config of hexo and scripts in package.json
  • Embedded variable for request header in http module of Nginx
  • Nginx's directive rewrite, alias and error_page
  • pathname of location and prepend of jQuery

Discussion

pic
Editor guide