Let's talk about internationalization (i18n) for Angular (not AngularJS, not Angular 2, just Angular 😉).
When it comes to JavaScript localization, one of the most popular frameworks is i18next. One of the most famous Angular extension for i18next is angular-i18next.
It was created back in April 2017 by Sergey Romanchuk.
i18next was created in late 2011. It's older than most of the libraries you will use nowadays, including your main frontend technology (React, Angular, Vue, ...). ➡️ sustainable
Based on how long i18next already is available open source, there is no real i18n case that could not be solved with i18next. ➡️ mature
i18next can be used in any javascript (and a few non-javascript - .net, elm, iOS, android, ruby, ...) environment, with any UI framework, with any i18n format, ... the possibilities are endless. ➡️ extensible
There is a plenty of features and possibilities you'll get with i18next compared to other regular i18n frameworks. ➡️ rich
Here you can find more information about why i18next is special and how it works.
Let's get into it...
Prerequisites
Make sure you have Node.js and npm installed. It's best, if you have some experience with simple HTML, JavaScript and basic Angular, before jumping to angular-i18next.
Getting started
Take your own Angular project or create a new one, i.e. with the Angular cli.
npx @angular/cli new my-app
To simplify let's remove the "generated" content of the angular-cli:
We are going to adapt the app to detect the language according to the user’s preference.
And we will create a language switcher to make the content change between different languages.
const i18nextOptions = { debug: true, fallbackLng: 'en', resources: { en: { translation: { "welcome": "Welcome to Your Angular App", "descr": "For a guide and recipes on how to configure / customize this project, check out {{-url}}." } }, de: { translation: { "welcome": "Willkommen zu Deiner Vue.js App", "descr": "Eine Anleitung und Rezepte für das Konfigurieren / Anpassen dieses Projekts findest du in {{-url}}." } } }, interpolation: { format: I18NextModule.interpolationFormat(defaultInterpolationFormat) } };
Does it work? - Of course!
And thanks to the language-detector, you can also try to switch the language with the query parameter ?lng=de:
Language Switcher
We like to offer the possibility to change the language via some sort of language switcher.
So let's add a footer section in our app.component.html file:
🥳 Awesome, you've just created your first language switcher!
Thanks to i18next-browser-languagedetector now it tries to detect the browser language and automatically use that language if you've provided the translations for it. The manually selected language in the language switcher is persisted in the localStorage, next time you visit the page, that language is used as preferred language.
Separate translations from code
Having the translations in our code works, but is not that suitable to work with, for translators.
Let's separate the translations from the code and pleace them in dedicated json files.
The app looks still the same, but the translations are now completely separated from the app and can be managed and released separately.
save missing translations
Thanks to the use of the saveMissing functionality, new keys gets added to locize automatically, while developing the app.
Just pass saveMissing: true in the i18next options and make sure you copy the api-key from within your locize project:
1 2 3 4 5 6 7 8 9 10 11 12
const i18nextOptions = { debug: true, saveMissing: true, // do not use the saveMissing functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production fallbackLng: 'en', backend: { projectId: 'my-locize-project-id', apiKey: 'my-api-key'// used for handleMissing functionality, do not add your api-key in a production build }, interpolation: { format: I18NextModule.interpolationFormat(defaultInterpolationFormat) } };
Each time you'll use a new key, it will be sent to locize, i.e.:
1
<p>{{ 'cool' | i18next: { defaultValue: 'This is very cool!' } }}</p>
With the help of the locize plugin, you'll be able to use your app within the locize InContext Editor.
Lastly, with the help of the auto-machinetranslation workflow, new keys not only gets added to locize automatically, while developing the app, but are also automatically translated into the target languages using machine translation:
const locizeOptions = { projectId: 'my-locize-project-id', apiKey: 'my-api-key'// used for handleMissing functionality, do not add your api-key in a production buildyour };
const i18nextOptions = { debug: true, fallbackLng: 'en', saveMissing: true, // do not use the saveMissing functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production backend: locizeOptions, locizeLastUsed: locizeOptions, interpolation: { format: I18NextModule.interpolationFormat(defaultInterpolationFormat) } };
exportfunctionappInit(i18next: ITranslationService) { return() => { let promise: Promise<I18NextLoadResult> = i18next // locize-lastused // sets a timestamp of last access on every translation segment on locize // -> safely remove the ones not being touched for weeks/months // https://github.com/locize/locize-lastused // do not use the lastused functionality in production: https://docs.locize.com/guides-tips-and-tricks/going-production .use(LastUsed) // locize-editor // InContext Editor of locize .use(locizePlugin) // i18next-locize-backend // loads translations from your project, saves new keys to it (saveMissing: true) // https://github.com/locize/i18next-locize-backend .use(LocizeApi) .use<any>(LanguageDetector) .init(i18nextOptions); return promise; }; }