Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2+ localization (i18n) rtl support

What is the best practice for adding right to left (rtl) support into a localized Angular 2+ app (e.g. for Hebrew and Arabic languages)? I looked through several tutorials including Internationalization (i18n) but none seem to be covering that. I would expect, for example, the html direction property (e.g. <html dir="rtl">) to be added along with translations defined in 18n attributes at the build step of the app.

like image 257
Timur Osadchiy Avatar asked Oct 23 '17 20:10

Timur Osadchiy


People also ask

How would you implement localization in angular using i18n tools?

Open the angular. json file and add the following configuration. Here we have added the configuration for the Spanish language. We have provided the path and format for the i18n file and set the locale to "es." When we execute the application, the app content will be served from the i18n file path provided.

How can we achieve internationalization using angular 2?

Internationalization is the process of supporting multiple languages in your applications. This can be accomplished in an Angular application through third party libraries, such as ngx-translate , or you can use the built-in i18n functionality.

What is angular RTL?

Angular Data Grid: RTL - Right To Left. RTL is used for displaying languages that go from Right to Left, eg Hebrew and Arabic. To get AG Grid to display in RTL format, set the property enableRtl=true .

How does localization work in angular?

Localization is the process of building versions of your app for different locales, including extracting text for translation into different languages, and formatting data for particular locales. A locale identifies a region (such as a country) in which people speak a particular language or language variant.


2 Answers

It is possible to add i18n-dir as described in the docs. So, the best approach I found so far is to add i18n-dir dir="ltr" (where ltr is a default direction) to the root element in the the root component template (e.g. app.component.html) like so:

<div i18n-dir dir="ltr">
    <!-- The rest of the content --> 
</div>

Once you generate translation files a corresponding trans-unit will appear in each of them with source containing default direction, which is ltr in this case. So, you just need to set the target of the unit to rtl for corresponding languages.

like image 156
Timur Osadchiy Avatar answered Sep 30 '22 05:09

Timur Osadchiy


The problem is the main index.html (and some other files) isn't a template and you can't do some stuff with it (e. g. translation). See this issue.

But because it is an easy process, I tried to do it myself:

  1. Create a translated version of your main index.html and insert it in a folder that named the code of your rtl language (fa in my case):

    src/fa/index.html:

    <!doctype html>
    <html lang="fa" dir="rtl">
    <head>
        <meta charset="utf-8">
        <title>عنوان برنامه</title>
        <base href="/fa/">
    
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="icon" type="image/x-icon" href="favicon.ico">
        <link rel="manifest" href="manifest.json">
        <meta name="theme-color" content="#1976d2">
    
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
     <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
    </head>
    <body>
    <app-root></app-root>
    <noscript>برای ادامه استفاده از این برنامه لازم است JavaScript را فعال کنید.</noscript>
    </body>
    </html>
    

    Especially see lang="fa" and dir="rtl" and native texts.

  2. In the related build configurations (in my case: production-fa and fa) in your angular.json file put:

    "index": "src/fa/index.html"
    

Done.


You can do same with other languages (Even ltrs! Because of other changes that we made in index.html).

To better understanding I also insert related build scripts in my package.json file:

    "start-fa": "ng serve --configuration=fa",
    "build-fa": "ng build --configuration=fa",
    "build-prod-fa": "ng build --prod --configuration=production-fa",

Bonus: What about manifest.json file (in case you want an installable PWA)?

The first step like above. Create a translated version in src/fa/manifest.json:

{
    "dir": "rtl",
    "lang": "fa",
    "name": "نام بلند برنامه",
    "short_name": "نام کوتاه",
    "theme_color": ...
    ...

But the second step is a little more difficult. I couldn't find a way to define its path. You can replace the original (src/manifest.json) with this one. You must do it BEFORE the build process starts (not after it by replacing dist/.../manifest.json; because @angular/service-worker needs to know its final state during the build process). So in your package.json:

"build-prod-fa": "cp src/fa/manifest.json src/manifest.json && ng build --prod --configuration=production-fa",

And revert it to its default version (in my case the default language is en) before the default production build:

"build-prod": "cp src/en/manifest.json src/manifest.json && ng build --prod",

Note that about manifest.json just production builds are important. Because serviceWorker is enabled only in these configurations by default (see your angular.json file).


I know this is not an ideal solution. Because you will need to edit your sources (in these two files) in multiple places.

like image 30
Mir-Ismaili Avatar answered Sep 30 '22 06:09

Mir-Ismaili