Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update localeData and LOCALE_ID for i18n sites dynamically during build in Angular 9?

I'm trying to build an application that supports multiple languages – up to 20 actually.

The default language is en-US. During the build the translated versions are created which works fine.

However, in all builds the LOCALE_ID is always en-US. So I can't rely on the locale in pipes etc. It is not updated with the locale set in the build confuguration.

I get this warning (here for German) during compilation for each locale as well:

Locale data for 'de-DE' cannot be found. No locale data will be included for this locale.


This is how the build config looks in angular.json:

"production-de": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.prod.ts"
    }
  ],
  "optimization": true,
  "outputHashing": "all",
  "sourceMap": false,
  "extractCss": true,
  "namedChunks": false,
  "aot": true,
  "extractLicenses": true,
  "vendorChunk": false,
  "buildOptimizer": true,
  "budgets": [
    {
      "type": "initial",
      "maximumWarning": "2mb",
      "maximumError": "5mb"
    },
    {
      "type": "anyComponentStyle",
      "maximumWarning": "6kb"
    }
  ],
  "outputPath": "dist/de",
  "baseHref": "/de/",
  "i18nLocale": "de-DE",
  "i18nFile": "src/locale/messages/messages.de.xlf",
  "i18nFormat": "xlf"
},

The application is build using this command:

ng build configuration=production-de

This is how my app.module.ts looks:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, LOCALE_ID } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { HttpClientModule } from '@angular/common/http';
import { registerLocaleData } from '@angular/common';

import localeEn from '@angular/common/locales/en';
import localeEnExtra from '@angular/common/locales/extra/en';

registerLocaleData(localeEn, 'en-US', localeEnExtra);

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    {
      provide: LOCALE_ID,
      useValue: 'en-US'
    }
  ],
  bootstrap: [
    AppComponent
  ]
})

export class AppModule { }

It seems that registerLocaleData and also the provider for LOCALE_ID are not updated during the build.

I already tried to remove registerLocaleData and the LOCALE_ID provider, as en-US is the default setting in Angular. But it doesn't change the behaviour.


Must I replace the app.module.ts as well with different values for registerLocaleData? This would be a huge overhead regarding the 20 languages.

Or is there a different but correct way to deploy the application in multiple languages?

Am I missing some configuration?

like image 216
lampshade Avatar asked Mar 02 '20 15:03

lampshade


1 Answers

With the help of David's comment I found that there where multiple mistakes in the configuration, because parts where taken from an Angular 8 project.

The config for i18n in Angular 9 is different and I found the solution by checking the schema of the angular.json file in ./node_modules/@angular/cli/lib/config/schema.json.

There's only one general build configuration now and I added i18n options to the actual project settings. This is what I added to the angular.json:

"projects": {
  "app": {
    "i18n": {
      "sourceLocale": "en",
      "locales": {
        "de": "src/locale/messages/messages.de.xlf"
      }
    },
    "architect": {
      "build": {
        "configurations": {
          "de": {
            "localize": ["de"]
          }
        }
      },
      "serve": {
        "configurations": {
          "de": {
            "browserTarget": "app:build:de"
          }
        }
      },

Now I can serve my application in any language using the CLI:

ng serve --configuration=de

And I can build all packages using:

ng build --prod --localize

Finally this has the effect that LOCALE_ID is set with the correct value at all times.

like image 158
lampshade Avatar answered Oct 05 '22 07:10

lampshade