You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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();
  }
}

补充说明

  1. 关于内置Resolver的冲突:你的AppModule中已经配置了AcceptLanguageResolver,该Resolver会自动处理Accept-Language头,若保留中间件,其设置的语言会覆盖Resolver的结果,可根据需求调整执行顺序或移除其中一个。
  2. 语言解析优化:上述代码仅做了简单的头信息拆分,若需要更严谨的语言权重解析(如处理en-US;q=0.9这类带权重的标识),可使用第三方库进行解析。
  3. 多语言生效验证:在控制器中可通过@I18n()装饰器注入I18nContext,调用i18nContext.t('key')验证翻译是否生效。

内容的提问来源于stack exchange,提问作者vijay s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:56:21