Angular i18n and Server Side Rendering with Angular Universal:Part 1
Tags: angular, npm, node
Published: 2020-09-04 14:30:33

Internationalization is the need of most modern apps today.If your application is developed in Angular, there are various libraries available, which you can use to present the app in multiple locales and reach out to your audience in various regions of the world.

Angular provides a module to accomplish the same. However, it is complex in comparison to some of the other libraries available for the purpose, which, you can integrate with your app.

Here, We will learn as to how we can use Angular i18n and then, we will  reason as to why it should be preferred over other strategies.  

Use Angular CLI to run below command
``` 
ng add @angular/localize
```
This will allow you to use Angular's Localization in your project.

Next, we mark  static text in template files for translations.
```
<p i18n >Welcome to Angular Internationalization!</p>  
```
Mark element attributes for translations by using i18n-attribute with any attribute of any element. You also can assign a meaning, description, and custom ID with the *i18n-attribute="meaning|description@@id"* syntax.

Below is an example for the same.
```
<input  type="password" i18n-placeholder ="passwordPlaceholder|Placeholder for Password@@001"  placeholder="password" name="password" /> 
```
Please note that meaning, description and Id are optional, and Angular will auto generate an Id for you, if you don't mention one.

Angular provides Data transformation pipes that use the LOCALE_ID token to format data according to the locale.

* DatePipe: Formats a date value.
* CurrencyPipe: Transforms a number to a currency string.
* DecimalPipe: Transforms a number into a decimal number string.
* PercentPipe: Transforms a number to a percentage string.

To override the value of LOCALE_ID, add the locale parameter, for Example,`{{amount | currency : 'en-US'}}`
For a list of available Locales please refer to [this.] (https://github.com/angular/angular/tree/master/packages/common/locales)

Now, that we have prepared templates for translation, we can proceed to process them.
#Extract Source Language File
Run the below command in Angular CLI.
```
ng xi18n  
```
This creates a source language file named *messages.xlf* in your project's root directory.
The xi18n command can read and write files in three translation formats:

* XLIFF 1.2 (default)
* XLIFF 2
* XML Message Bundle (XMB)

You can specify the translation format explicitly with the        `--format` command option.

The *messages.xlf* looks like below.Notice that, it has  translation units,with an Id generated for it. It also captures other metadata, like file location and line number.

``` 
<trans-unit id="7d1069de6c435fab320e5305cbaf139af1b0189f" datatype="html">
        <source>Welcome!</source>
        <context-group purpose="location">
        <context context-type="sourcefile">app/login/login.component.html</context>
          <context context-type="linenumber">23</context>
        </context-group>
      </trans-unit>
```
Duplicate the *messages.xlf* file  for each locale of your interest, and rename it.For example, you can rename it to *messages.pa.xlf* for Punjabi Language.           
Please note that below code snippet has an additional target tag for translation of the source Language text.                        
                                                       
``` 
<trans-unit id="7d1069de6c435fab320e5305cbaf139af1b0189f" datatype="html">
        <source>Welcome!</source>
        <target> ਜੀ ਆਇਆਂ ਨੂੰ !</target>
        <context-group purpose="location">
        <context context-type="sourcefile">app/login/login.component.html</context>
          <context context-type="linenumber">23</context>
        </context-group>
      </trans-unit>
```
 Similarly, add target tags to all translation units, in all the *messages.lang.xlf* files, corresponding to the number of languages your app may be supporting.
 
#Define Locales in the Configuration
In *angular.json* , Under build's *Configurations*, define a configuration for each locale.Notice that, `en-US` is Locale_ID for English, You can refer [here] (https://github.com/angular/angular/tree/master/packages/common/locales) for other Languages. 

```
"en-US": {
              "outputPath": "dist/browser/en",
              "baseHref": "/en/",
              "i18nLocale": "en-US",
              "i18nFormat": "xlf",
              "i18nFile": "src/messages.xlf",
              "i18nMissingTranslation": "error",
              "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"
                }
              ]
            }
          }
        },    
```
`outputPath` signifies path in the root directory of the Project, 
where this build will be generated, once run.Angular i18n supports `aot` by default. `baseHref` indicates the ref on the website, which loads the locale.
 
Similarly, Under _angular.json's_ , serve Configurations, define serve configs for each locale. Here `production` indicates the default, and `en-US` indicates application served in English. You should include all the locales your app is supporting. `demoproject` is the name of the project here.
```
"production": {
              "browserTarget": "demoproject:build:production"
            },
            "en-US": {
              "browserTarget": "demoproject:build:en-US"
            },
```
>Please note, that build and serve configurations are defined in _angular.json_ for each locale, which indicates that, a separate build and deployment will be created and run for each locale.

Now, you can build and run the application in your desired locale, by  the following command on CLI. Below is an example for Punjabi Language.

```
ng build --configuration=pa-Guru && ng serve --configuration=pa-Guru

```
In case, you want multiple locales to be running in parallel, add the `--port` switch with serve command, to serve the app on a different port for a different locale.

This gives us a basic implementation of Angular i18n, with separate build and deployment for each locale. But,Our goal is to be able to switch the locales from the Url itself. Also, it is important to understand the motivation to pick angular i18n mechanism instead of other simpler available libraries.

This will be covered in a separate blog post. That is where Server Side Rendering comes into play. 

[click here](https://dev.to/prabhjeet6/server-side-rendering-with-angular-universal-3fjd) for Part 2 of the blog post.