React i18next如何同时加载前端与后端的多语言翻译文件?
解决方案:i18next同时加载前后端翻译文件
方案1:使用链式后端插件(推荐,无需手动写逻辑)
i18next官方提供了i18next-chained-backend插件,可以按优先级顺序加载多个后端的翻译资源,自动合并翻译结果,重复key会被后加载的翻译覆盖。
步骤1:安装依赖
npm install i18next-chained-backend i18next-http-backend
步骤2:修改i18next配置
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import Backend from 'i18next-http-backend'; import ChainedBackend from 'i18next-chained-backend'; i18n .use(initReactI18next) .use(ChainedBackend) // 替换原来的单个Backend,改用链式后端 .init({ ns:['common', 'translation'], defaultNS : 'common', fallbackLng: 'zh', // 可根据自己需求配置 // 链式后端配置 backend: { // 后端实例列表,按加载顺序排列,后加载的翻译会覆盖同key的前序翻译 backends: [ Backend, // 第一个加载前端本地翻译 Backend // 第二个加载后端翻译 ], // 每个backend对应的配置,顺序和上面backends数组一一对应 backendOptions: [ // 第一个backend(本地)的配置 { loadPath: "/locales/{{lng}}/{{ns}}.json" }, // 第二个backend(后端)的配置 { loadPath: "http://localhost:5000/locales/{{lng}}/{{ns}}.json", // 如果后端接口需要跨域配置可以加下面的参数 crossDomain: true, // 后端请求失败时不抛出错误,继续使用已加载的本地翻译 requestOptions: { cache: 'default' } } ] } });
优先级说明
- 如果需要本地静态翻译优先,覆盖后端同key翻译:把后端backend放在backends数组第一位,本地放在第二位
- 如果需要后端动态翻译优先,覆盖本地同key翻译:按上面示例的顺序配置即可
方案2:自定义Backend插件(无额外依赖)
如果不想引入新的依赖,可以自己实现一个简单的自定义backend,依次请求本地和后端的翻译文件,合并后返回。
配置示例如下:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // 自定义Backend实现 const CustomMultiSourceBackend = { type: 'backend', init(services, backendOptions, i18nextOptions) { // 初始化操作,这里可以存储配置 this.localPath = backendOptions.localPath || "/locales/{{lng}}/{{ns}}.json"; this.remotePath = backendOptions.remotePath || "http://localhost:5000/locales/{{lng}}/{{ns}}.json"; }, async read(language, namespace, callback) { // 替换路径中的变量 const localUrl = this.localPath.replace('{{lng}}', language).replace('{{ns}}', namespace); const remoteUrl = this.remotePath.replace('{{lng}}', language).replace('{{ns}}', namespace); try { // 并行请求本地和后端翻译,单端请求失败不会影响另一端 const [localRes, remoteRes] = await Promise.allSettled([ fetch(localUrl).then(res => res.ok ? res.json() : {}), fetch(remoteUrl).then(res => res.ok ? res.json() : {}) ]); // 合并翻译,后面对象的key会覆盖前面的 const mergedTranslations = { ...(localRes.status === 'fulfilled' ? localRes.value : {}), ...(remoteRes.status === 'fulfilled' ? remoteRes.value : {}) }; callback(null, mergedTranslations); } catch (err) { callback(err, null); } } }; i18n .use(initReactI18next) .use(CustomMultiSourceBackend) // 使用自定义backend .init({ ns:['common', 'translation'], defaultNS : 'common', fallbackLng: 'zh', backend: { // 自定义配置,分别指定本地和后端路径 localPath: "/locales/{{lng}}/{{ns}}.json", remotePath: "http://localhost:5000/locales/{{lng}}/{{ns}}.json" } });
内容的提问来源于stack exchange,提问作者Rojan Subedi
相关产品推荐
相关产品推荐

