众所周知,国内互联网行业已经进入存量市场,竞争激烈、利润微薄。一些公司为了摆脱困境,将目标转向了海外,海外市场相比国内,竞争小、利润高,潜力大。未来数年,出海会成为越来越多公司的重要战略。
如果你所在的公司要走出国门,相应面向客户的web和H5产品都要国际化。国际化最重要的就是多语言的支持。我将以React框架为例,介绍在前端项目中如何搭建多语言。
基础项目搭建
首先创建一个React模板项目
npx create-react-app oversea-react-app --template typescript
然后下载i18n相应的依赖包
npm i i18next react-i18next
i18next
和 react-i18next
不用过多介绍,就是i18n提供翻译能力的基础依赖包。
然后在项目src目录下,新建i18n目录,新建如下几个文件
- src
- i18n
- index.ts
- zh-cn.json
- en-us.json
- i18n
其中index.tsx文件代码如下:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import enUs from './en-us.json';
import zhCn from './zh-cn.json';
export const SUPPORTED_LANG = [
'zh-cn',
'en-us',
];
// 配置参数的文档: https://www.i18next.com/overview/configuration-options
const option = {
fallbackLng: 'zh', // 默认语言
debug: process.env.NODE_ENV !== 'production',
resources: { // 支持的语言
en: {
translation: enUs,
},
zh: {
translation: zhCn,
},
},
interpolation: {
escapeValue: false, // not needed for react!!
},
};
// 注入react-i18next实例并初始化
i18n.use(initReactI18next)
.init(option);
export default i18n;
上面第三行和第四行代码引入了两个json文件,分别是英文和中文的翻译资源
{
"multiLanguage": "多语言"
}
{
"multiLanguage": "multi-language"
}
不要忘记在项目主文件 src/index.ts 中导入i18n
import './i18n/index'
最后在项目业务组件中使用i18n翻译功能
import React from 'react';
import { useTranslation } from 'react-i18next';
const Language: React.FC = () => {
// useTranslation 返回的对象包含一个 t 方法,这个方法可以翻译文本
const { t } = useTranslation();
return <>
<div>{t('multiLanguage')}</div>
</>
}
export default Language;
在浏览器中可以看到,文本已经被成功翻译了
检测浏览器默认语言
项目中已经成功引入了多语言,但在实际应用场景中,是需要根据浏览器默认语言作为页面的展示语言的,这就要使用到能检测浏览器语言的插件i18next-browser-languagedetector
下载依赖并在 i8n/index.ts文件中引入
import LanguageDetector from 'i18next-browser-languagedetector';
...
// 注入react-i18next实例并初始化
i18n.use(LanguageDetector) // 检测用户当前使用的语言
.use(initReactI18next)
.init(option);
重启项目,查看浏览器的Application控制面板,可以看到浏览器默认语言在Local Storage中做了缓存
再将浏览器默认语言设置为英语
清空Local Storage的缓存并刷新浏览器,页面展示了英语,并且Local Storage中缓存也设置为英语
语言切换
前端实现国际化的过程中,还要提供能切换页面展示语言的功能
我们将业务组件做如下改动,核心改动点就是在切换语言时修改缓存数据i18nextLng
import React, {useState} from 'react';
import { useTranslation } from 'react-i18next';
const Language: React.FC = () => {
const { t } = useTranslation();
const lang = window.localStorage.getItem('i18nextLng') || 'zh';
const [language, setLanguage] = useState(lang);
const languageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setLanguage(e.target.value);
// 切换语言时修改缓存数据
window.localStorage.setItem('i18nextLng', e.target.value);
// 重新加载页面
window.location.reload();
}
return <>
<select value={language} onChange={languageChange}>
<option value="zh">简体中文</option>
<option value="en">English</option>
</select>
<br />
<div>{t('multiLanguage')}</div>
</>
}
export default Language;
当然i8n官方更推荐使用changeLanguage方法,调用i18n.changeLanguage
,会自动修改缓存数据i18nextLng
import React, {useState} from 'react';
import { useTranslation } from 'react-i18next';
const Language: React.FC = () => {
const { t, i18n } = useTranslation();
...
const languageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
...
// 切换展示语言,会自动修改缓存数据i18nextLng
i18n.changeLanguage(e.target.value);
...
}
...
}
看看代码展示效果,当语言切换成简体中文,页面展示了中文,同时缓存数据也修改为zh
插值表达式
在实际应用场景中,可能会遇到一段话中夹杂了变量,这时候i18n的插值表达式就派上用场了。
插值表达式的语法是使用两个大花括号包裹变量
{
"desc": "作者是{{author}},当前时间是{{currentTime}}"
}
{
"desc": "The author is {{author}}, current time is {{currentTime}}"
}
在视图层,t函数支持传入第二个参数,是一个对象,对象的属性名对应插值表达式中花括号包裹的变量,属性值作为插值最终被t方法替换到翻译文本中。
<div>
{t('desc', {
author: '远方的戈多',
language,
currentTime: new Date().toLocaleString()
})}
</div>
最终显示效果
结语
本文介绍了React项目中支持多语言的基础搭建,同时介绍了项目默认语言设置为浏览器的首选语言,切换语言以及插值表达式这些常用功能。
在下一篇中,我们将介绍如何使用js脚本进行各语言的自动翻译,以及通过脚本如何查找项目中未翻译的文本,敬请期待。
原文链接:https://juejin.cn/post/7333631025757224979 作者:远方的戈多