locale
支持在 icejs 应用中快速开启国际化功能。
快速开始
安装插件
$ 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
后,则将关闭国际化路由;
redirect
: 选填,默认值是 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
语言。
关闭国际化路由
插件默认开启国际化路由。如需关闭,则需要在 build.json 中增加以下配置:
{
"plugins": [
[
"build-plugin-ice-i18n", {
"locales": ["en-US", "zh-CN"],
"defaultLocale": "zh-CN",
+ "i18nRouting": false
}
]
]
}
获取语言信息
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 为例:
// src/app.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>
)
}
}
}
// src/locales/index.ts
import { LOCALES } from './locales';
const LOCALES = {
ENGLISH: 'en-US',
ZH_CN: 'zh-CN'
};
const messages = {
[LOCALES.ENGLISH]: {
homeTitle: 'Home',
aboutTitle: 'About',
},
[LOCALES.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 () {
history.push('/about');
setLocale('zh-CN');
}
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",
+ "redirect": true
}
]
]
}
SSG
在 SSG 场景下,将根据在 build.json
中配置的 locales
字段,在 build
阶段会生成不同国际化语言对应的 html:
├── build
| ├── 404.html
| ├── about
| | └── index.html
| ├── en-US
| | ├── about
| | | └── index.html
| | └── index.html
| ├── index.html
参考链接
- nextjs i18n-routing:https://nextjs.org/docs/advanced-features/i18n-routing
- umi locale 文档:https://umijs.org/zh-CN/plugins/plugin-locale
- umi locale RFC:https://github.com/umijs/umi-next/issues/7
- nextjs-i18n-example:https://github.com/luhc228/nextjs-i18n-app
💥 Big Bang feature request