So I am currently working on an ongoing NestJS project, my lead assigned me a task to implement a way to return different error to the frontend depending on the language in the header of the request, after a bit of research I concluded that i18n would be my best bet, after following the documentation to the T, I went to try it in postman, but instead of return the message it returned the variable name, so lets say there a variable in the JSON file called test = HelloWorld, instead of HelloWorld, it is return test.
I tried searching for fixes or suggestion on previous post, went over the documentation again, and even tried copying code from my leads other project that has i18n setup with but still nothing, I don't know what I am missing, so I would be very thankful if someone can help.
I Will provide some relevant files from the project, so if someone can spot what is wrong.
package.json
{
"name": "nest-experiments",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/mongoose": "^9.2.2",
"@nestjs/platform-express": "^9.0.0",
"axios": "^1.4.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"mongodb": "^5.5.0",
"mongoose": "^7.2.1",
"nestjs-i18n": "^10.2.6",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "29.5.1",
"@types/mongoose": "^5.11.97",
"@types/node": "18.16.12",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.5.0",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "29.1.0",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.2.0",
"typescript": "^5.0.0"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
nest-cli.json
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"assets": [
{ "include": "i18n/**/*", "watchAssets": true }
]
}
}
app.module.ts I know this code here is bit different from the current documentation but this code from my lead project
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import {
AcceptLanguageResolver,
CookieResolver,
HeaderResolver,
I18nJsonLoader,
I18nModule,
QueryResolver,
} from 'nestjs-i18n';
import * as path from 'path';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PointsModule } from './points/points.module';
import { SlackModule } from './slack/slack.module';
import { UsersModule } from './users/users.module';
@Module({
imports: [PointsModule, MongooseModule.forRoot('mongodb+srv://sharbelabousabha:2639Xq0y3W9ATVeO@cluster0.horwrkd.mongodb.net/?retryWrites=true&w=majority'), SlackModule, UsersModule,
I18nModule.forRoot({
fallbackLanguage: 'en',
loaderOptions: {
path: path.join(__dirname, '/i18n/'),
watch: true,
},
resolvers: [
// eslint-disable-next-line sort-keys
{ use: QueryResolver, options: ['lang', 'locale', 'l'] },
new HeaderResolver(['x-custom-lang']),
AcceptLanguageResolver,
new CookieResolver(['lang', 'locale', 'l']),
],
})
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule { }
app.service.ts
import { Injectable } from '@nestjs/common';
import { I18nContext, I18nService } from 'nestjs-i18n';
@Injectable()
export class AppService {
constructor(private readonly i18n: I18nService) {}
getHello(): string {
console.log({ lang: I18nContext.current().lang })
return this.i18n.translate('Created.Success');
}
}
Turns out you also need to put the name of the JSON file at the beginning, So in this case instead of Created.Success
, it had to be user.Created.Success