插件的配置分为两部分:CLI 配置(modern.config.ts)和运行时配置(modern.runtime.ts)。两者需要结合使用,CLI 配置用于插件的基础设置,运行时配置用于 i18next 的初始化选项。
函数类型的配置(如 SDK 加载函数)只能在运行时配置(modern.runtime.ts)中设置,不能在 CLI 配置中设置。这是因为 CLI 配置在构建时执行,无法序列化函数。
在 modern.config.ts 中配置插件选项:
import { i18nPlugin } from '@modern-js/plugin-i18n';
export default defineConfig({
plugins: [
i18nPlugin({
localeDetection: {
// 语言检测配置
},
backend: {
// 后端资源加载配置
},
}),
],
});localeDetection 用于配置语言检测相关选项:
如果启用了 localePathRedirect,detection 配置必须放在 CLI 配置(modern.config.ts)中,因为服务端插件需要根据此配置来获取语言信息并进行路径重定向。
interface BaseLocaleDetectionOptions {
/** 是否启用路径重定向,启用后会在 URL 中添加语言前缀 */
localePathRedirect?: boolean;
/** 是否启用 i18next 语言检测器 */
i18nextDetector?: boolean;
/** 支持的语言列表 */
languages?: string[];
/** 默认回退语言 */
fallbackLanguage?: string;
/** 自定义检测配置 */
detection?: LanguageDetectorOptions;
/** 忽略自动重定向的路由列表或函数
*
* 可以是一个字符串数组(路径模式),或一个函数来判断是否应该忽略重定向。
* 支持精确匹配和前缀匹配(如 '/api' 会匹配 '/api' 和 '/api/users')。
*
* @example
* // 字符串数组
* ignoreRedirectRoutes: ['/api', '/admin']
*
* // 函数
* ignoreRedirectRoutes: (pathname) => pathname.startsWith('/api')
*/
ignoreRedirectRoutes?: string[] | ((pathname: string) => boolean);
}
interface LocaleDetectionOptions extends BaseLocaleDetectionOptions {
/** 按入口配置语言检测(多入口场景) */
localeDetectionByEntry?: Record<string, BaseLocaleDetectionOptions>;
}示例:
i18nPlugin({
localeDetection: {
localePathRedirect: true,
i18nextDetector: true,
languages: ['zh', 'en', 'ja'],
fallbackLanguage: 'en',
detection: {
order: ['path', 'cookie', 'header'],
lookupCookie: 'i18next',
caches: ['cookie'],
},
},
});backend 用于配置资源加载方式:
自动检测:插件会在以下场景自动检测并启用 backend:
如果配置了 loadPath 或 addPath:由于你已经指定了资源路径,backend 会自动启用(enabled: true),无需检测 locales 目录。
如果没有配置 backend:插件会自动检测以下位置是否存在 locales 目录:
{项目根目录}/locales{项目根目录}/config/public/localesserver.publicDir 配置的目录:{项目根目录}/{publicDir}/locales如果目录存在且包含 JSON 文件,backend 会自动启用。
如果显式设置 enabled: false:不会进行自动检测,backend 保持禁用状态。
这种自动检测机制可以在 locales 目录不存在时减少不必要的 backend 注册,提升性能。
interface BaseBackendOptions {
/** 是否启用后端资源加载 */
enabled?: boolean;
/** 资源文件加载路径(HTTP 后端) */
loadPath?: string;
/** 缺失翻译保存路径(可选) */
addPath?: string;
/** 链式后端的缓存命中模式(仅在同时配置 `loadPath` 和 `sdk` 时生效)
*
* - `'none'`(默认):如果第一个后端返回了资源,则停止,不再尝试下一个后端
* - `'refresh'`:尝试从下一个后端刷新缓存并更新缓存
* - `'refreshAndUpdateStore'`:尝试从下一个后端刷新缓存,更新缓存并同时更新 i18next 资源存储。
* 这允许先显示 FS/HTTP 资源,然后 SDK 资源会异步更新它们。
*
* @default 'refreshAndUpdateStore' 当同时配置 loadPath 和 sdk 时
*/
cacheHitMode?: 'none' | 'refresh' | 'refreshAndUpdateStore';
/** SDK 加载函数(自定义后端)
*
* 注意:在 CLI 配置中只能设置为 `true` 或字符串标识符来启用 SDK 模式。
* 实际的 SDK 函数必须在运行时配置(`modern.runtime.ts`)中通过 `initOptions.backend.sdk` 提供。
*
* 当同时配置 `loadPath`(或 FS 后端)和 `sdk` 时,插件会自动使用 `i18next-chained-backend`
* 来链式加载多个后端。加载顺序为:
* 1. HTTP/FS 后端(主要)- 先从 `loadPath` 或文件系统加载,用于快速初始显示
* 2. SDK 后端(更新)- 从 SDK 函数加载,用于更新/刷新翻译
*
* 使用 `cacheHitMode: 'refreshAndUpdateStore'`(默认)时,FS/HTTP 资源会立即显示,
* 然后 SDK 资源会异步加载以更新翻译。
*/
sdk?: I18nSdkLoader | boolean | string;
}
interface BackendOptions extends BaseBackendOptions {
/** 按入口配置后端(多入口场景) */
backendOptionsByEntry?: Record<string, BaseBackendOptions>;
}示例:
1. 仅使用 HTTP/FS 后端:
你可以显式启用 backend:
i18nPlugin({
backend: {
enabled: true,
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
});或者只需配置 loadPath 或 addPath,backend 会自动启用:
i18nPlugin({
backend: {
// enabled 会自动设置为 true
loadPath: '/locales/{{lng}}/{{ns}}.json',
},
});无配置时的自动检测:
如果你完全不配置 backend,插件会自动检测 locales 目录:
i18nPlugin({
// 没有 backend 配置 - 插件会自动检测 locales 目录
localeDetection: {
languages: ['zh', 'en'],
fallbackLanguage: 'en',
},
});如果 locales 目录存在且包含 JSON 文件,backend 会自动启用,使用默认的 loadPath: '/locales/{{lng}}/{{ns}}.json'。
2. 链式后端(推荐):同时使用 HTTP/FS 后端和 SDK 后端
当 backend.enabled = true 且配置了 sdk 时,如果未显式配置 loadPath,将自动使用默认的 loadPath 并启用链式后端:
i18nPlugin({
backend: {
enabled: true,
// 当未配置 loadPath 时,将自动使用默认的 '/locales/{{lng}}/{{ns}}.json'
sdk: true, // SDK 后端
// cacheHitMode: 'refreshAndUpdateStore', // 默认值,可省略
},
});你也可以显式配置 loadPath:
i18nPlugin({
backend: {
enabled: true,
loadPath: '/locales/{{lng}}/{{ns}}.json', // HTTP/FS 后端
sdk: true, // SDK 后端
},
});在 modern.runtime.ts 中提供 SDK 函数:
export default defineRuntimeConfig({
i18n: {
initOptions: {
backend: {
sdk: async options => {
// SDK 实现
if (options.lng && options.ns) {
return await mySdk.getResource(options.lng, options.ns);
}
},
},
},
},
});使用链式后端时,系统会:
/locales/{{lng}}/{{ns}}.json 加载资源并立即显示(快速显示基础翻译)这样可以确保用户快速看到页面内容,同时后台加载最新的翻译资源。
3. 仅使用 SDK 后端:
如果你需要禁用 HTTP/FS 后端并仅使用 SDK 后端,可以显式设置 loadPath: '':
i18nPlugin({
backend: {
enabled: true,
loadPath: '', // 显式禁用 HTTP/FS 后端
sdk: true, // 仅使用 SDK 后端
},
});
当仅使用 SDK 后端时,必须在 modern.runtime.ts 中提供实际的 SDK 函数,否则将回退到 HTTP/FS 后端。
如果项目有多个入口,可以为每个入口单独配置:
i18nPlugin({
localeDetection: {
localePathRedirect: true,
languages: ['zh', 'en'],
fallbackLanguage: 'en',
// 为特定入口覆盖配置
localeDetectionByEntry: {
admin: {
localePathRedirect: false, // admin 入口不使用路径重定向
},
},
},
backend: {
enabled: true,
// 为特定入口覆盖配置
backendOptionsByEntry: {
admin: {
loadPath: '/admin/locales/{{lng}}/{{ns}}.json',
},
},
},
});在 src/modern.runtime.ts 中可以配置运行时选项:
import { defineRuntimeConfig } from '@modern-js/runtime';
import i18next from 'i18next';
// 建议创建一个新的 i18next 实例,避免使用全局默认实例
const i18nInstance = i18next.createInstance();
export default defineRuntimeConfig({
i18n: {
// 使用自定义 i18next 实例(可选)
i18nInstance: i18nInstance,
// i18next 初始化选项
initOptions: {
fallbackLng: 'en',
supportedLngs: ['zh', 'en'],
// 其他 i18next 配置选项
},
},
});如果需要使用自定义的 i18next 实例,可以在运行时配置中提供:
import { defineRuntimeConfig } from '@modern-js/runtime';
import i18next from 'i18next';
// 创建自定义实例
const customI18n = i18next.createInstance({
// 自定义配置
});
export default defineRuntimeConfig({
i18n: {
i18nInstance: customI18n,
},
});initOptions 会传递给 i18next 的 init 方法,支持所有 i18next 配置选项:
如果启用了 localePathRedirect,detection 配置应该在 CLI 配置中设置,而不是在 initOptions 中。这是因为服务端插件需要读取 CLI 配置中的 detection 选项来进行语言检测和路径重定向。
export default defineRuntimeConfig({
i18n: {
initOptions: {
// 语言相关
lng: 'en',
fallbackLng: 'en',
supportedLngs: ['zh', 'en'],
// 命名空间相关
ns: ['translation', 'common'],
defaultNS: 'translation',
// React 相关
react: {
useSuspense: false,
},
// 其他 i18next 选项
interpolation: {
escapeValue: false,
},
},
},
});如果使用 SDK 后端,需要在运行时配置中提供实际的 SDK 函数:
函数类型的配置只能在运行时配置中设置。在 CLI 配置中,sdk 只能设置为 true 或字符串标识符来启用 SDK 模式,实际的函数实现必须在 modern.runtime.ts 中提供。
在 modern.config.ts 中启用 SDK 模式:
i18nPlugin({
backend: {
enabled: true,
sdk: true, // 启用 SDK 模式
},
});在 modern.runtime.ts 中提供 SDK 函数:
import { defineRuntimeConfig } from '@modern-js/runtime';
import type { I18nSdkLoader } from '@modern-js/plugin-i18n/runtime';
const mySdkLoader: I18nSdkLoader = async options => {
if (options.all) {
// 加载所有资源
return await fetchAllResources();
}
if (options.lng && options.ns) {
// 加载单个资源
const response = await fetch(`/api/i18n/${options.lng}/${options.ns}`);
return response.json();
}
// 处理其他情况
return {};
};
export default defineRuntimeConfig({
i18n: {
initOptions: {
backend: {
sdk: mySdkLoader,
},
},
},
});