We will need to localize for each locale we need to support. A locale refers to the general set of preferences for the considerations mentioned above that tend to be shared within a region of the world, typically a country. Each locale is represented by a Unicode locale identifier, which specifies the language code and the locale extension.
Angular's default locale is 'en-US', which is the language code 'en' (English) as spoken in the region ‘United States of America’. An app localized for 'en-US' will be subtly different from an app localized for 'en-GB' which is English as spoken in Great Britain. For example, in the US dates are (bafflingly) formatted mm/dd/yyyy, whereas here in the UK we use the more sensible dd/mm/yyyy approach. This minor difference can result in a major error incomprehension.
To make things interesting let's localize our demo app for Arabic as spoken in Iraq, aka 'ar-IQ' and English as spoken in the UK, aka 'en-GB'. We'll use English as the default this time.
Steps to Implement Angular Location in Application
So, if we want to implement the Localization in the Angular Application, then we need to perform the following steps –
Step 1
First of all, we need to create an Angular Application using the Angular CLI command. For that run the command
ng new localeDemo
Step 2
Now, we need to install the Angular Language package by using the below command –
- npm install @angular/localize
Step 3
Now, open the polyfill.ts file and add the below line of code in that file –
- import 'zone.js/dist/zone';
- import '@angular/localize/init'
Step 4
Now, in the application open the app.component.html file and change the existing code with this one –
- <h1 style="color: red;">Static Locale Change</h1>
-
- <div class="container-fluid">
-
- <div class="row">
- <h1 style="color: blue;" i18n>Hello i18n!</h1>
- <h1 style="color: blue;" i18n="header">An introduction header for this sample</h1>
- <h1 style="color: blue;" i18n="@@country">India</h1>
- </div>
-
- </div>
In the above example, we can see that we use the i18n attribute in the <h1> tag. i18n is a custom attribute that can be recognized by the Angular Tools and compiler. After compilation, the compiler removes this attribute. It is not a directive. To translate the context properly, sometimes we need to mention a description or id against the i18n attribute. for that purpose, in the 2nd <h1> tag, we have used description text as “header” whereas in the next one we use the id value against the i18n attribute as “@@country”.
Step 5
Now, we need to create the translation file with the help of the Angular CLI command –
- ng xi18n --output-path src/locale
This command will create messages.xlf file –
- <?xml version="1.0" encoding="UTF-8" ?>
- <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
- <file source-language="en-US" datatype="plaintext" original="ng2.template">
- <body>
- <trans-unit id="4150330030790364157" datatype="html">
- <source>Hello i18n!</source>
- <target>Hello i18n!!!!</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">6</context>
- </context-group>
- </trans-unit>
-
- <trans-unit id="9207070150930908421" datatype="html">
- <source>An introduction header for this sample</source>
- <target>Translated by the Angular Locale</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">7</context>
- </context-group>
- <note priority="1" from="description">header</note>
- </trans-unit>
-
- <trans-unit id="country" datatype="html">
- <source>India</source>
- <target>India</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">8</context>
- </context-group>
- </trans-unit>
- </body>
- </file>
- </xliff>
Now we can copy this file to create the other language translation file like – messages.fr.xlf
- <?xml version="1.0" encoding="UTF-8" ?>
- <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
- <file source-language="en-US" datatype="plaintext" original="ng2.template">
- <body>
- <trans-unit id="4150330030790364157" datatype="html">
- <source>Hello i18n!</source>
- <target>Bonjour i18n!!!!</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">6</context>
- </context-group>
- </trans-unit>
-
- <trans-unit id="9207070150930908421" datatype="html">
- <source>An introduction header for this sample</source>
- <target>Traduit par Angular Locale</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">7</context>
- </context-group>
- <note priority="1" from="description">header</note>
- </trans-unit>
-
- <trans-unit id="country" datatype="html">
- <source>India</source>
- <target>Inde</target>
- <context-group purpose="location">
- <context context-type="sourcefile">src/app/static-locale/static.component.html</context>
- <context context-type="linenumber">8</context>
- </context-group>
- </trans-unit>
- </body>
- </file>
- </xliff>
This file contains a list of multiple <trans-unit> tags. This tag will contain all the content which is marked for the translation or where we use the i18n attribute. We can also observe that each <trans-unit> tag has an id property associated with it. This unique id will be generated by default for each tag that was marked with the i18n attribute. We can also customize the id by providing a name prefixed with @@ as we have done in the 3rd <h1> tag in the HTML file. Hence, the id for <h1> tag is “country” as we defined it.
Step 6
Now, we already define the locale-related language translation file. Now, we need to update the build configuration related to the locale. For that, we need to perform the below changes in the angular.json file –
- {
- "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
- "cli": {
- "analytics": false
- },
- "version": 1,
- "newProjectRoot": "projects",
- "projects": {
- "angular-language-demo": {
- "projectType": "application",
- "schematics": {
- "@schematics/angular:application": {
- "strict": true
- }
- },
- "root": "",
- "sourceRoot": "src",
- "prefix": "app",
- "i18n": {
- "sourceLocale": "en-US",
- "locales": {
- "en": {
- "translation": "src/locale/messages.xlf"
- },
- "es": {
- "translation": "src/locale/messages.es.xlf"
- },
- "hi": {
- "translation": "src/locale/messages.hi.xlf"
- },
- "fr": {
- "translation": "src/locale/messages.fr.xlf"
- }
- }
- },
- "architect": {
- "build": {
- "builder": "@angular-devkit/build-angular:browser",
- "options": {
- "outputPath": "dist/angular-language-demo",
- "index": "src/index.html",
- "main": "src/main.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.app.json",
- "aot": true,
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "src/styles.css"
- ],
- "scripts": [],
- "localize":true
- },
- "configurations": {
- "production": {
- "fileReplacements": [
- {
- "replace": "src/environments/environment.ts",
- "with": "src/environments/environment.prod.ts"
- }
- ],
- "optimization": true,
- "outputHashing": "all",
- "sourceMap": false,
- "namedChunks": false,
- "extractLicenses": true,
- "vendorChunk": false,
- "buildOptimizer": true,
- "budgets": [
- {
- "type": "initial",
- "maximumWarning": "500kb",
- "maximumError": "1mb"
- },
- {
- "type": "anyComponentStyle",
- "maximumWarning": "2kb",
- "maximumError": "4kb"
- }
- ]
- },
- "en": {
- "localize": ["en"]
- },
- "es": {
- "localize": ["es"]
- },
- "hi": {
- "localize": ["hi"]
- },
- "fr": {
- "localize": ["fr"]
- }
- }
- },
- "serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
- "options": {
- "browserTarget": "angular-language-demo:build"
- },
- "configurations": {
- "production": {
- "browserTarget": "angular-language-demo:build:production"
- },
- "en": {
- "browserTarget": "angular-language-demo:build:en"
- },
- "es": {
- "browserTarget": "angular-language-demo:build:es"
- },
- "hi": {
- "browserTarget": "angular-language-demo:build:hi"
- },
- "fr": {
- "browserTarget": "angular-language-demo:build:fr"
- }
- }
- },
- "extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
- "options": {
- "browserTarget": "angular-language-demo:build"
- }
- },
- "test": {
- "builder": "@angular-devkit/build-angular:karma",
- "options": {
- "main": "src/test.ts",
- "polyfills": "src/polyfills.ts",
- "tsConfig": "tsconfig.spec.json",
- "karmaConfig": "karma.conf.js",
- "assets": [
- "src/favicon.ico",
- "src/assets"
- ],
- "styles": [
- "src/styles.css"
- ],
- "scripts": []
- }
- },
- "lint": {
- "builder": "@angular-devkit/build-angular:tslint",
- "options": {
- "tsConfig": [
- "tsconfig.app.json",
- "tsconfig.spec.json",
- "e2e/tsconfig.json"
- ],
- "exclude": [
- "**/node_modules/**"
- ]
- }
- },
- "e2e": {
- "builder": "@angular-devkit/build-angular:protractor",
- "options": {
- "protractorConfig": "e2e/protractor.conf.js",
- "devServerTarget": "angular-language-demo:serve"
- },
- "configurations": {
- "production": {
- "devServerTarget": "angular-language-demo:serve:production"
- }
- }
- }
- }
- }
- },
- "defaultProject": "angular-language-demo"
- }
Step 7
Now, we need to update the package.json file as below –
- "scripts": {
- "ng": "ng",
- "start": "ng serve --configuration=production",
- "start:hi": "ng serve --configuration=hi",
- "start:fr": "ng serve --configuration=fr",
- "start:en": "ng serve --configuration=en",
- "start:es": "ng serve --configuration=es",
- "build": "ng build",
- "build:prod": "ng build --configuration=production",
- "test": "ng test",
- "lint": "ng lint",
- "e2e": "ng e2e"
- },
Step 8
Now, first, run the command to build the project for the production environment. When we build the project by using ng build –prod command, in the production environment, it will prepare separate files for each locale.
Now, if we want to start the application, we can run the application with a specific locale with the npm run start command –
Similarly, if we want to run the application using a french locale, then we need to run the below command -
In that case, the output will be as below -
Conclusion
In this article, we discussed how to implement the localization using the Angular Framework in any web application. Also, we discussed the basic concept of localization along with the sample example. I hope, this article will help you. Any feedback or query related to this article is most welcome.