I18n Internationalization

For developing the multi-language application, build-in I18n support by egg-i18n plugin

# Default Language

Default en-US. Assume that we want to switch the default language to Simplified Chinese:

// config/config.default.js
exports.i18n = {
defaultLocale: 'zh-CN',
};

# Switch Language

Here we have some ways to switch the application's current language (Modified records will set to the cookie locale), the next request will use the language setting directly.

Priority from high to low:

  1. query: /?locale=en-US
  2. cookie: locale=zh-TW
  3. header: Accept-Language: zh-CN,zh;q=0.5

If want to modify parameter name of query or cookie

// config/config.default.js
exports.i18n = {
queryField: 'locale',
cookieField: 'locale',
// Cookie default expired after one year, the unit is ms if set as Number
cookieMaxAge: '1y',
};

# Writing I18n Multi-language Documents

Configuration of multi-language are independent, stored in config/locale/*.js

- config/locale/
- en-US.js
- zh-CN.js
- zh-TW.js

Not only take effects in the application directory, but also in the directory of framework or plugin config/locale

Note: It's locale, not locals.

Example:

// config/locale/zh-CN.js
module.exports = {
Email: '邮箱',
};

Or using JSON file:

// config/locale/zh-CN.json
{
"Email": "邮箱"
}

# Getting Multi-language Texts

Use __ (Alias: gettext) function to get the multi-language texts under locale directory

Note: __ is two underscores

Take above multi-language configuration as example:

ctx.__('Email')
// zh-CN => 邮箱
// en-US => Email

If texts contain format function like %s%j, we can call by the way similar to util.format()

// config/locale/zh-CN.js
module.exports = {
'Welcome back, %s!': '欢迎回来,%s!',
};

ctx.__('Welcome back, %s!', 'Shawn');
// zh-CN => 欢迎回来,Shawn!
// en-US => Welcome back, Shawn!

Support array, subscript and placeholder, such as

// config/locale/zh-CN.js
module.exports = {
'Hello {0}! My name is {1}.': '你好 {0}! 我的名字叫 {1}。',
};

ctx.__('Hello {0}! My name is {1}.', ['foo', 'bar'])
// zh-CN => 你好 foo!我的名字叫 bar。
// en-US => Hello foo! My name is bar.

# Use in Controller

class HomeController extends Controller {
async index() {
const ctx = this.ctx;
ctx.body = {
message: ctx.__('Welcome back, %s!', ctx.user.name)
// or use gettext, it is a alias of __ function
// message: ctx.gettext('Welcome back', ctx.user.name)
user: ctx.user,
};
}
}

# Use in View

Assume we are using template engine Nunjucks

<li>{{ __('Email') }}: {{ user.email }}</li>
<li>
{{ __('Welcome back, %s!', user.name) }}
</li>
<li>
{{ __('Hello {0}! My name is {1}.', ['foo', 'bar']) }}
</li>