nestjs-i18n Translation handlebars templates not working

Viewed 309

Handlebars template not translating by nestjs-i18n

app.module.ts

@Global()
@Module({
imports: [
      I18nModule.forRoot({
      fallbackLanguage: 'en',
      loaderOptions: {
        path: path.join(__dirname, '/i18n/'),
        watch: true,
      },
      resolvers: [
        { use: HeaderResolver, options: ['lang'] },
        AcceptLanguageResolver,
      ],
    }),
  ],
})
export class AppModule {}

mail.module.ts doc

@Module({
  imports: [
    ConfigModule.forRoot(),
    MailerModule.forRootAsync({
      inject: [I18nService],
      useFactory: (i18n: I18nService) => ({
        transport: {
          host: process.env.MAILER_HOST,
          port: +process.env.MAILER_PORT,
          ignoreTLS: true,
          secure: true,
          auth: {
            user: process.env.MAILER_USER,
            pass: process.env.MAILER_PASS,
          },
        },
        defaults: {
          from: '"No Reply" <no-reply@localhost>',
        },
        preview: true,
        template: {
          dir: path.join(__dirname, '../resources/mail/templates/'),
          adapter: new HandlebarsAdapter({ t: i18n.hbsHelper }),
          options: {
            strict: true,
          },
        },
      }),
    }),
  ],
  providers: [MailService],
  exports: [MailService],
})
export class MailModule {}

src/i18n/fr/common.json "HELLO": "Bonjour",

src/i18n/en/common.json "HELLO": "Hello",

src/resources/mail/templates/test.hbs

<!doctype html>
<html>
  <body>
    <h1>{{ t 'common.HELLO' }}</h1>
  </body>
</html>

call api endpoint with curl curl -X POST http://localhost:8009/api/message -H "lang: fr"

in email preview i see

<!doctype html>
<html>
  <body>
    <h1>Hello</h1>
  </body>
</html>

instead of Bonjour

Translations in another places (f.e. validation) working ok

What I'm doing wrong?

2 Answers

Same issue. As I can see in src/services/i18n.service.ts, property i18nLang is required in option.data.root. I think it means that we should provide property i18nLang in object, which we pass to template. In my case, I get lang value from I18nContext from controller.

F.E. I pass object in tis form

  context: {
    user,
    i18nLang,
  },

According to my experience I18nService doesnt have access to data from Resolvers. Have you tried with I18nContext or getI18nContextFromRequest? When I used them Resolvers were able to set the language.

I did another check and saw that Stas Pyatnicyn's solution works definitely.

I think he mentions this line in the hbsHelper function

const lang = options.lookupProperty(options.data.root, 'i18nLang');

But I couldnt follow up what exactly lookupProperty() does. If he can explain it, it would be very much appreciated.

Its really weird that there is no documentation about this and thanks him a lot for finding out the solution.

Related