Romanchuk / angular-i18next

angular v10+ integration with i18next v19.4+
MIT License
131 stars 33 forks source link

Providing namespaces in modules doesn't work #71

Closed dpeger closed 3 years ago

dpeger commented 3 years ago

I'm trying to use angular-i18next to localize angular libraries. To avoid clashes in the i18n keys I want every module to use it's own namespace. But providing I18NEXT_NAMESPACE on a module level doesn't work as expected as only one module's namespace is being used by all modules. Providing the namespace on a component level makes this component use the correct namespace but as a module contains several components this becomes somewhat redundant...

I setup a stackblitz to ilustrate the problem:

https://stackblitz.com/edit/i18next-module-namespaces

I have 2 modules

Module1:

@NgModule({
  imports: [CommonModule, I18NextModule],
  providers: [
    {
      provide: I18NEXT_NAMESPACE,
      useValue: 'module1'
    }
  ],
  exports: [Module1Component],
  declarations: [Module1Component]
})
export class Module1Module {}

Module2:

@NgModule({
  imports: [CommonModule, I18NextModule],
  providers: [
    {
      provide: I18NEXT_NAMESPACE,
      useValue: 'module2'
    }
  ],
  exports: [Module2Component],
  declarations: [Module2Component]
})
export class Module2Module {}

But despite the different providers, module1's component will use the 'module2' namespace.

If I specify a different namespace on a component in module1 this namespace is used.

dpeger commented 3 years ago

After reading some more and more I suppose this behavior is due to the nature of Angular's DI. That is all eagerly loaded modules will share the same namespace. Lazy loaded modules however will get their own namespace.

Romanchuk commented 3 years ago

@dpeger Yes, providing same token in same injector overrides previous value. You can try to provide namespaces via viewProviders in components. Never tried it yet. Also you can dynamicaly load namespaces via routes data (you can find use case in docs)