nestjs-i18n集成Handlebars邮件模板翻译不生效问题求助
使用nestjs-i18n时Handlebars模板无法正常翻译问题
问题根因
核心配置错误出在MailModule的模板适配器初始化逻辑:你在MailerModule.forRootAsync的工厂函数(应用启动阶段执行,无请求上下文)中直接传入了静态的i18n.hbsHelper引用,helper执行时无法通过Nest的请求上下文存储读取到当前请求头携带的fr语言标识,永远回退到配置的默认语言en。
项目中参数校验等场景翻译正常,是因为这类逻辑运行在请求生命周期内,i18n服务可以正常通过resolver解析到当前请求的语言。
修复方案
优先选择显式传参的方案,兼容性最高,同步、异步、队列场景下都能正常工作:
- 替换原有的静态hbsHelper绑定,自定义模板t helper,优先读取模板上下文传入的语言参数:
// MailModule中MailerModule的template配置修改为 template: { dir: path.join(__dirname, '../resources/mail/templates/'), adapter: new HandlebarsAdapter({ t: (key: string, options: any) => { const targetLang = options.data?.root?.lang || 'en'; return i18n.t(key, { lang: targetLang }); } }), options: { strict: true, }, },
- 在发送邮件的业务逻辑中,显式获取当前请求的语言,传入模板上下文:
// MailService中示例代码 @Injectable() export class MailService { constructor( private readonly mailerService: MailerService, private readonly i18n: I18nService ) {} async sendTestMail(to: string) { // 读取当前请求上下文解析出的语言 const currentLang = this.i18n.lang; await this.mailerService.sendMail({ to, subject: 'Test', template: 'test', context: { // 将语言显式传给模板 lang: currentLang } }) } }
如果仅在请求处理流程中同步发送邮件,没有异步延迟、队列发送的需求,也可以直接在I18nModule根配置中添加viewEngine: 'hbs'配置开启CLS上下文透传,无需修改helper和传参逻辑,但该方案在请求销毁后的异步场景下会失效,不推荐生产环境使用。
内容的提问来源于stack exchange,提问作者Alex K
相关产品推荐
相关产品推荐

