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.
问题:
回答1:
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.
回答2:
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:
Create a translated version of your main
index.html
and insert it in a folder that named the code of yourrtl
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"
anddir="rtl"
and native texts.In the related build configurations (in my case:
production-fa
andfa
) in yourangular.json
file put:"index": "src/fa/index.html"
Done.
You can do same with other languages (Even ltr
s! 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.
回答3:
As of 2017, it appears that the Angular team is too busy and too few to add right-to-left (rtl) support to the angular-translate module (https://github.com/angular-translate/angular-translate/issues/260).
Not a big deal though, because it's pretty easy to do this with just native JS...
document.body.setAttribute("dir", "rtl");
In my experience, HTML5 does a pretty good job of getting rtl support done correctly.