1,安装依赖
yarn add i18next react-i18next i18next-browser-languagedetector
2,创建i18n.jsx
import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import translationEN from './locales/en/translation.json';
import translationZH from './locales/zh/translation.json';
const resources = {
en: {
translation: translationEN
},
zh: {
translation: translationZH
},
};
i18n
// detect user language
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
// for all options read: https://www.i18next.com/overview/configuration-options
.init({
lng:'zh', // default
whitelist: ['en', 'zh'],
fallbackLng: 'en',
debug: true,
resources,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
detection: {
order: ['path'],
// checkWhitelist: true,
}
}, () => {
});
function setLang() {
let urlLanguage = 'zh';
// 如果在地址栏中带有语言选项:http://localhost:3000/en/home
// 也可以使用其他方案:http://localhost:3000/home?lang=en
// 或者放到缓存中读取。localStorage.getItem('lang')
if (window.location.pathname.indexOf('/en') !== -1) {
urlLanguage = 'en';
}
if (urlLanguage !== i18n.language) {
i18n.changeLanguage(urlLanguage);
}
}
setLang()
window.onpopstate = setLang
export default i18n;
3,创建translation.json
{
"home": {
"login": "登录"
}
}
实际开中,需要配置多个json文件,很难保证相互之间的一致性。
所以写了一个小工具,只需要维护一份json,然后自动生成对应的语言包。
createLanguage.js
let fs = require('fs')
let lang = fs.readFileSync(`${__dirname}/lang.json`, {encoding: 'utf8'})
let locales = {
en: {},
zh: {},
}
for (let i in locales) {
let newLang = splitLang(JSON.parse(lang), i)
fs.writeFileSync(`${__dirname}/${i}/translation.json`, JSON.stringify(newLang, null, 4), {encoding: 'utf8'})
}
function splitLang(langObj, local) {
for (let i in langObj) {
if (langObj && langObj.hasOwnProperty(i)) {
if (langObj[i].en) {
langObj[i] = langObj[i][local] || langObj[i].en
} else {
let item = langObj[i]
if (item && typeof item === 'object') {
splitLang(item, local)
}
}
}
}
return langObj
}
console.log('\n\nlanguage build successfull!!!\n\n')
lang.json
{
"home": {
"login": {
"en": "Login",
"zh": "登录"
}
}
}
然后把生成命令添加到package.json中,就可以自动生成指定的语言包了。
如果临时修改了lang.json,也可以手动执行package中的命令:createLanguageFile
4,入口文件中引入i18n.jsx:
5,路由中配置多语言:
6,页面中使用语言项:
切换语言实现逻辑:
const changeLanguage = (lng: string) => {
const oldLanguage = i18n.language;
if (oldLanguage === lng) {
return;
}
// 切换语言 i18n.changeLanguage
i18n.changeLanguage(lng, function () {
if (Array.isArray(i18n.options.fallbackLng)) {
let pathName = pathname === '/' ? '' : pathname
// 从地址中,删除旧的语言选项
pathName = pathName.replace(new RegExp(`\\/(${Object.keys(langName).join('|')})`, 'i'), '')
let url = '/' + lng + pathName
window.history.pushState({}, '', url)
}
})
};
<li onClick="changeLanguage('en')">English</li>
<li onClick="changeLanguage('zh')">中文</li>