本文详解如何在基于 Handlebars 的 Sails.js 应用中无缝集成 i18next(配合 i18next-http-middleware),通过自定义 HTTP 中间件完成语言检测、初始化与上下文注入,使视图可直接调用 t() 函数实现国际化翻译。
本文详解如何在基于 handlebars 的 sails.js 应用中无缝集成 i18next(配合 i18next-http-middleware),通过自定义 http 中间件完成语言检测、初始化与上下文注入,使视图可直接调用 `t()` 函数实现国际化翻译。
Sails.js 虽未原生封装 i18next,但其灵活的中间件机制(尤其是 config/http.js 中的 middleware.order 和自定义函数支持)为集成提供了理想入口。关键在于:将 i18next 初始化逻辑封装为一次性中间件,并确保其早于路由处理执行,从而为后续请求上下文(如 req.t)注入翻译能力。
✅ 正确集成步骤
1. 安装依赖
npm install i18next i18next-http-middleware
2. 配置 i18next 选项(config/i18n.js)
// config/i18n.js
module.exports.i18n = {
fallbackLng: 'en',
supportedLngs: ['en', 'zh', 'ja'],
preload: ['en', 'zh', 'ja'], // 预加载语言资源(需配合后端资源加载器,如 i18next-fs-backend)
ns: ['common', 'page'],
defaultNS: 'common',
detection: {
order: ['querystring', 'cookie', 'header'],
caches: ['cookie']
}
};⚠️ 注意:若使用 JSON 文件作为翻译资源,需额外引入 i18next-fs-backend 并在 init() 中配置 backend: { loadPath: './locales/{{lng}}/{{ns}}.json' };Sails 默认不提供文件加载能力,需自行实现或使用内存内静态资源。
3. 注册 i18next 中间件(config/http.js)
// config/http.js
const i18next = require('i18next');
const middleware = require('i18next-http-middleware');
const i18nConfig = require('./i18n').i18n;
module.exports.http = {
middleware: {
// 确保 'i18n' 在路由前执行(如置于 'poweredBy', 'router' 之前)
order: [
'i18n',
'poweredBy',
'cookieParser',
'session',
'bodyParser',
'compress',
'router',
'www',
'favicon'
],
i18n: (function () {
// 仅初始化一次(IIFE),避免重复调用 init()
i18next
.use(middleware.LanguageDetector)
.init(i18nConfig);
// 返回 i18next-http-middleware 提供的处理函数
return middleware.handle(i18next, {
ignoreRoutes: ['/health', '/swagger'] // 可选:跳过无需翻译的路径
});
})()
}
};4. 在 Handlebars 模板中使用翻译
Sails 自动将 req.t 注入视图上下文,因此可在 .hbs 文件中直接调用:
<!-- views/homepage.hbs -->
<h1>{{t "welcome.title"}}</h1>
<p>{{t "welcome.message"}}</p>
<a href="/?lng=zh">{{t "switch.to.chinese"}}</a>✅ 原理说明:i18next-http-middleware.handle() 会自动挂载 req.t(翻译函数)、req.language(当前语言码)和 res.locals.t(供模板访问),无需手动传递。
5. (可选)全局辅助函数增强可读性
在 api/helpers/translate.js 中创建便捷 helper:
module.exports = async function (inputs, exits) {
const { key, options, req } = inputs;
if (!req?.t) return exits.error(new Error('i18next not initialized on request'));
return exits.success(req.t(key, options));
};并在模板中调用(需在 config/views.js 启用 helpers):
{{translate key="error.network" options=(hash count=3)}}? 关键注意事项
- 初始化时机:必须使用立即执行函数(IIFE)包裹 i18next.init(),否则 Sails 多进程下可能重复初始化导致冲突;
- 语言检测优先级:LanguageDetector 默认按 querystring → cookie → header 顺序探测,可通过 i18nConfig.detection.order 调整;
- 性能优化:生产环境建议启用 caches: ['cookie'] 并设置合理 cookieExpirationDate,减少重复探测;
- 热更新限制:Sails 开发模式下修改语言文件不会自动重载——需重启服务或集成 i18next-chained-backend + fs.watch 实现热刷新。
完成以上配置后,启动应用,访问 /homepage?lng=zh 即可看到中文翻译内容。整个流程完全遵循 Sails 架构规范,无需侵入核心逻辑,兼具可维护性与扩展性。










