如何在NestJS中配置nestjs-i18n中间件正确获取Accept-Language头
NestJS i18n 中间件完善方案
已完成的配置
app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { PrismaModule } from './config/database'; import { SessionModule } from './modules/session/session.module'; import { I18nModule, QueryResolver, AcceptLanguageResolver, HeaderResolver, } from 'nestjs-i18n'; import * as path from 'path'; import { I18nMiddleware } from './common/hooks/i18n/i18n.middleware'; @Module({ imports: [ PrismaModule, SessionModule, ConfigModule.forRoot({ isGlobal: true }), I18nModule.forRoot({ fallbackLanguage: 'en', fallbacks: { 'en-CA': 'fr', 'en-*': 'en', 'fr-*': 'fr', pt: 'pt-BR', }, loaderOptions: { path: path.join(__dirname, '/i18n/'), watch: true, }, resolvers: [ { use: QueryResolver, options: ['lang'], }, new HeaderResolver(['x-content-lang']), AcceptLanguageResolver, ], }), ], controllers: [], providers: [], }) export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(I18nMiddleware).forRoutes('*'); } }
语言文件结构
src/ └── i18n/ ├── en/ │ └── en.json ├── fr/ │ └── fr.json └── ...(其他语言目录)
nest-cli.json
{ "$schema": "https://json.schemastore.org/nest-cli", "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { "assets": [ { "include": "i18n/**/*", "watchAssets": true } ] } }
问题说明
已安装nestjs-i18n@10.2.6并完成基础配置,希望通过Accept-Language请求头获取用户偏好语言以实现翻译,现有自定义中间件需要完善逻辑,使获取到的语言生效。
完善后的中间件代码
import { Injectable, NestMiddleware } from '@nestjs/common'; import { FastifyRequest, FastifyReply } from 'fastify'; import { I18nService } from 'nestjs-i18n'; @Injectable() export class I18nMiddleware implements NestMiddleware { // 注入I18nService用于语言处理 constructor(private readonly i18nService: I18nService) {} async use(req: FastifyRequest, res: FastifyReply, next: () => void) { const acceptLangHeader = req.headers['accept-language']?.toString(); if (acceptLangHeader) { // 解析Accept-Language头,提取优先级最高的语言标识 const preferredLang = acceptLangHeader.split(',')[0].trim(); // 验证语言是否在支持列表中,不支持则使用 fallback 语言 const validLang = this.i18nService.getSupportedLanguages().includes(preferredLang) ? preferredLang : this.i18nService.getFallbackLanguage(); // 设置当前请求上下文的语言 await this.i18nService.setCurrentLanguage(validLang); } next(); } }
补充说明
- 关于内置Resolver的冲突:你的
AppModule中已经配置了AcceptLanguageResolver,该Resolver会自动处理Accept-Language头,若保留中间件,其设置的语言会覆盖Resolver的结果,可根据需求调整执行顺序或移除其中一个。 - 语言解析优化:上述代码仅做了简单的头信息拆分,若需要更严谨的语言权重解析(如处理
en-US;q=0.9这类带权重的标识),可使用第三方库进行解析。 - 多语言生效验证:在控制器中可通过
@I18n()装饰器注入I18nContext,调用i18nContext.t('key')验证翻译是否生效。
内容的提问来源于stack exchange,提问作者vijay s
相关产品推荐
相关产品推荐

