我正在使用react和react-i18next来本地化我的应用程序。问题是在更新本地化文件之后。有时我的json文件的旧版本会缓存在浏览器中。如果用户清理缓存,这是可以解决的,但我不能指望用户知道如何清理缓存。JSON文件位于public\locales下。
我刚刚想好如何在i18next-translation.json文件中禁用缓存
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
fallbackLng: "en",
debug: true,
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
requestOptions: {
cache: 'no-store',
},
},
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
});
这不是一个理想的解决方案。更好的解决方案是,每次构建后都需要重新检索翻译文件。但现在这种情况没有发生,这种感觉是哈希没有添加到翻译文件中如何在新建后防止缓存?
我在使用i18next-localstorage-backend
时遇到了同样的问题,即在浏览器中使用localStorage
。
我只是在init选项中添加了一个defaultVersion
,但为了在每次构建时获得一个新版本,我必须生成一个随机的版本号。
这是我的i18n.ts
文件:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import resourcesToBackend from 'i18next-resources-to-backend';
import Backend from "i18next-chained-backend";
import LocalStorageBackend from "i18next-localstorage-backend";
function genRandonNumber(length : number) {
const chars = '0123456789';
const charLength = chars.length;
let result = '';
for ( var i = 0; i < length; i++ ) {
result += chars.charAt(Math.floor(Math.random() * charLength));
}
return result;
}
const LOCAL_DOMAINS = ["localhost", "127.0.0.1"];
const HASH = genRandonNumber(10);
i18n
.use(Backend)
// detect user language
.use(LanguageDetector)
// pass the i18n instance to react-i18next.
.use(initReactI18next)
// init i18next
.init({
// default fallback will be french
fallbackLng: 'fr',
// default namespace to load
ns: 'header',
// load languages ressources with lazy loading and caching client side
backend: {
backends: [
LocalStorageBackend, // primary ressources (cache = window.localStorage)
resourcesToBackend((language, namespace, callback) => {
import(`/public/locales/${language}/${namespace}.json`)
.then((resources) => {
callback(null, resources)
})
.catch((error) => {
callback(error, null)
})
}) // fallback ressources (json)
],
backendOptions: [{
expirationTime: 24 * 60 * 60 * 1000 * 7, // 7 days
defaultVersion: "v" + HASH // generate a new version every build to refresh
}]
},
// debug only in dev
debug: LOCAL_DOMAINS.includes(window.location.hostname),
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
});
i18n.on('languageChanged', () => {
document.documentElement.lang = i18n.language;
});
export default i18n;
我的i18n
实例有点复杂,但最终它会:
- 使用
localStorage
可以减少网络连接并实现更快的翻译 - 由于使用了名称空间,因此只加载给定页面所需的
JSON
文件 - 每次新建都更新
localStorage
如果使用多个后端(JSON
文件和localStorage
(,则必须使用i18next-chained-backend
。