Internationalization
Translate your app with Angular's @angular/localize. Mark text with i18n or $localize, extract it with ng extract-i18n, and load the right translation when the app starts. One bundle serves every language.
What's different on Lynx
- Translations load at runtime. Angular's build-time translation, with one build per language, isn't supported. Your app calls
loadTranslations()before it starts. - The language comes from the host app. AngularLynx reads
appLocalefrom the host app's GlobalData. The iOS and Android apps thatng build --platformgenerates don't set it yet, so your app uses thesourceLocalefrom angular.json. - There's no
Intl.$localizeand Angular's pipes don't need it. Code that callsIntldirectly needs a polyfill. - Switching language means restarting the app, for most text. Template
i18ntext andLOCALE_IDdon't change after they're first used. Some strings can switch live.
Set up
This command:
- installs
@angular/localize, at the same version as@angular/core - adds
"i18n": { "sourceLocale": "en-US" }to your project in angular.json - adds
@angular/localize/initto the build'spolyfills, so$localizeexists before your code runs - adds
@angular/localizetotypesin tsconfig.app.json, so TypeScript knows$localize - adds
provideLocale()to your app config
provideLocale() sets Angular's LOCALE_ID from appLocale, falling back to sourceLocale, then to en-US.
Mark text for translation
i18non an element marks its text for translation.@@greetingsets the message ID.$localizemarks a string in TypeScript.:@@welcome:sets its ID, and:userName:names the placeholder for${this.userName()}.- Give every message an
@@ID. Translation files are keyed by ID, and a custom ID stays the same when you edit the English text.
Extract the messages
ng extract-i18n needs a target in angular.json, because Angular can't pick an extractor for the AngularLynx builder on its own. Add one under architect:
Then run it:
It writes src/locale/messages.json with every message in your source language:
Copy it to one file per language, such as messages.fr.json, and translate the values. Keep placeholders like {$userName} as they are.
The JSON format's translations object is exactly what loadTranslations() takes. Angular's default XLIFF format also works with translation tools, but you then convert each file to an object yourself.
Load a translation
Call loadTranslations() in main.ts, before bootstrapApplication():
getLynxAppLocale()readsappLocalewithout Angular's dependency injection, so it works before the app starts. It returnsundefinedwhen the host app hasn't set one.- Load before bootstrap. Angular translates template text and
$localizestrings when it creates each component, using whatever was loaded at that moment. - Messages without a translation show the source text and log a warning.
Read the current locale
Inject LynxLocale for the locale as a signal:
locale() returns appLocale, or the same fallbacks as provideLocale(). Angular's pipes use LOCALE_ID instead. To format dates, numbers or currency for a locale other than en-US, register its data with registerLocaleData().
Switch language while the app runs
A $localize string inside a computed() can switch live. Make it depend on a signal, then replace the translations and change the signal:
Template i18n text, $localize strings outside a computed(), and LOCALE_ID keep the language the app started with. To change those, the app has to start again with the new appLocale.
Add an Intl polyfill
AngularLynx doesn't include an Intl polyfill. Without one, Number.prototype.toLocaleString() formats numbers the en-US way for every locale, and Intl.* calls throw.
If your code or a library needs Intl, install FormatJS's polyfills and list them in the build's polyfills, in this order:
Add the locale-data files for each language you support. The build runs these files before your app on both threads. Check them on a device, because Lynx's JavaScript engine is older than a browser's (see The JavaScript environment).
Related
- Locale API reference:
LynxLocale,provideLocale()andgetLynxAppLocale() - Schematics: what
add-i18nchanges - Pass data from your native app: setting GlobalData such as
appLocale - i18n example
- Angular's i18n guide
