Skip to main content

国际化 I18n

2.0.0

支持在 icejs 应用中快速开启国际化功能,核心特性包括:

  • 支持自动处理和生成国际化路由
  • 支持自动重定向到偏好语言对应的页面
  • 完美支持 SSR 和 SSG,获得更好的 SEO 优化
  • 不耦合任何一个 i18n 库,你可以选择你喜欢的解决方案

注意:MPA 应用暂不支持

快速开始

安装插件

$ npm i build-plugin-ice-i18n -D

使用

build.json 中使用插件:

{
"plugins": [
[
"build-plugin-ice-i18n", {
"locales": ["en-US", "zh-CN"],
"defaultLocale": "zh-CN"
}
]
]
}

上面的 en-USzh-CN 是国际化语言的缩写,它们均遵循标准的 UTS 语言标识符。比如:

  • zh-CN:中文(中国)
  • zh-HK:中文(香港)
  • en-US:英文(美国)
  • de: 德文

插件选项

  • locales: 必填,该应用支持的国际化语言
  • defaultLocale: 必填,该应用默认的国际化语言
  • i18nRouting: 选填,默认值是 true。设置为 false 后,则将关闭国际化路由
  • autoRedirect: 选填,默认值是 false。设置为 true 后,则将重定向到偏好语言对应的页面

国际化路由

国际化路由是指在页面路由中包含当前页面的国际化语言。开启该插件后,ice.js 会自动处理路由。

举个例子,假如在 src/routes.ts 有以下的路由配置:

const routerConfig = [
{
path: '/home',
exact: true,
component: Home,
},
]

同时在 build.json 中有以下配置:

{
"plugins": [
[
"build-plugin-ice-i18n", {
"locales": ["en-US", "zh-CN", "nl-NL"],
"defaultLocale": "zh-CN"
}
]
]
}

则以下路由是可访问的:

  • /home:显示 zh-CN 语言,默认语言没有前缀路由
  • /en-US/home:显示 en-US 语言
  • /nl-NL/home:显示 nl-NL 语言

获取语言信息

useLocale

useLocale hook 用于在组件中获取和修改语言信息。

import { useLocale } from 'ice';

function Home() {
const [locale, setLocale] = useLocale();

console.log('locale: ', locale); // 'en-US'
return (
{/* 切换语言为 zh-CN */}
<div onClick={() => setLocale('zh-CN')}>Set zh-CN</div>
)
}

调用 setLocale 方法时,将更新 cookie 中的 ice_locale 的值。

getLocale

getLocale 用于获取当前页面的语言。

import { getLocale } from 'ice';

console.log(getLocale()); // 'zh-CN'

getAllLocales

getAllLocales 用于获取当前配置的所有语言。

import { getAllLocales } from 'ice';

console.log(getAllLocales()); // ['zh-CN', 'en-US']

getDefaultLocale

getDefaultLocale 用于获取默认配置的语言。

import { getDefaultLocale } from 'ice';

console.log(getDefaultLocale()); // 'zh-CN'

使用 i18n 库

插件不耦合任何 i18n 库,用户可以自行选择。目前社区比较流行的 i18n 库有 react-intl, react-i18next 等等。

在 icejs 中使用 i18n 库很简单,以 react-intl 为例:

import { IntlProvider } from 'react-intl';
import { useLocale } from 'ice';
import { messages } from './locales';

function LocaleProvider({ children }) {
const [locale] = useLocale();
const defaultLocale = getDefaultLocale();

return (
<IntlProvider
messages={messages[locale]}
locale={locale}
defaultLocale={defaultLocale}
>
{children}
</IntlProvider>
);
}

const appConfig = {
app: {
addProvider: ({ children }) => {
return (
{/* 添加 Provider */}
<LocaleProvider>{children}</LocaleProvider>
)
}
}
}

切换语言

我们可以使用 <Link> 组件或者 history.push/replace 方法进行语言切换:

import { useLocale, getAllLocales, Link, useLocation } from 'ice';

export default function LocaleSwitcher() {
const location = useLocation();
const [activeLocale, setLocale] = useLocale();
const allLocales = getAllLocales();
const otherLocales = allLocales.filter((locale) => activeLocale !== locale);

function switchAboutZHCNPage () {
setLocale('zh-CN');
history.push('/about');
}
return (
<div>
<div onClick={() => switchAboutZHCNPage()}>
切换到中文
</div>
<ul>
{
otherLocales.map((locale: string) => {
return (
<li key={locale}>
<Link
to={location.pathname}
onClick={() => setLocale(locale)}>
{locale}
</Link>
</li>
);
})
}
</ul>
</div>
);
}

自动重定向

根据当前语言环境自动跳转到对应的国际化路由。其中,语言环境的识别顺序的规则如下:

  • CSR:cookie 中 ice_locale 的值 > window.navigator.language > defaultLocale
  • SSR:cookie 中 ice_locale 的值 > res 的 Header 中的 Accept-Language > defaultLocale

build.json 开启方式如下:

{
"plugins": [
[
"build-plugin-ice-i18n", {
"locales": ["en-US", "zh-CN"],
"defaultLocale": "zh-CN",
+ "autoRedirect": true
}
]
]
}

SSG

SSG 场景下,将根据在 build.json 中配置的 locales 字段,在 build 阶段会生成不同国际化语言对应的 html:

├── build
| ├── 404.html
| ├── about
| | └── index.html
| ├── en-US
| | ├── about
| | | └── index.html
| | └── index.html
| ├── index.html