国际化 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-US
和 zh-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 为例:
- app.ts
- locales.ts
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>
)
}
}
}
const messages = {
'en-US': {
homeTitle: 'Home',
aboutTitle: 'About',
},
'zh-CN': {
homeTitle: '首页',
aboutTitle: '关于',
},
};
切换语言
我们可以使用 <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