Localization
Last modified on Wed 25 Sep 2024

This chapter covers various best practices for localization and handling translations in your Angular application.

Localization library

Currently, the preferred library of choice for handling localization in Angular is Transloco. Transloco allows you to define translations for your content in different languages and switch between them easily at runtime. It exposes a rich API to manage translations efficiently and cleanly. It provides multiple plugins that will improve your development experience. The setup is quite easy, and you can find it in the documentation, so we won't discuss it here.

Usage

transloco pipe

The easiest way to handle translation is through a pipe. To use it, simply import TranslocoModule in your component and pass the translation key to the pipe in your component template.

<p>{{'common.exampleKey' | transloco}}</p>

translate function

In some cases, we need to translate the keys in the component itself rather than in the template. Inject the service into your component and then use the translate function by passing in the key you wish to translate.

private translocoService = inject(TranslocoService)
private exampleTranslatedKey = this.translocoService.translate('common.exampleKey')

Note: Besides the ability to translate keys, the TranslocoService also provides many more functionalities, such as changing the selected language.

Pluralization support

Besides just translating a single key, sometimes we need to handle singular and plural versions of a single word. While it might be simple for some languages like English, it can be quite complicated for languages like Croatian, German, etc. Transloco does not support this out of the box, but the @jsverse/transloco-messageformat plugin allows you to handle pluralization with ease.

Installation

To enable the plugin, pass provideTranslocoMessageformat() to the providers array of either appConfigFactory or TranslocoRootModule if using modules.

Language plural rules

To properly translate singular and plural forms, we need to first check the plural rules for the language we are writing our translation keys. The standard table with the rules can be found here. Essentially, you need to check the needed categories for a specific language and create the translation keys accordingly. The following examples will be done for the English language, and they represent a small set of available features that will cover almost all cases. For additional functionalities, refer to the official plugin documentation.

Usage

The categories for English are one for singular, and other for any value higher than one. To define the pluralization key, we must provide the following:

Plural

{
 "minutes": "{minutes, plural, one {minute} other {minutes}}"
}
<p>{{ "minutes" | transloco : { minutes: 1 } }}</p>
// minute


<p>{{ "minutes" | transloco : { minutes: 5 } }}</p>
// minutes

Ordinal

For ordinals, we need to set the type to selectordinal

{
 "minutesOrdinal": "{minutes, selectordinal, one {st} two {nd} few {rd} other {th}}",
}
<p>1{{ "minutes" | transloco : { minutes: 1 } }}</p>
// 1st


<p>2{{ "minutes" | transloco : { minutes: 2 } }}</p>
// 2nd


<p>3{{ "minutes" | transloco : { minutes: 3 } }}</p>
// 3rd


<p>4{{ "minutes" | transloco : { minutes: 4 } }}</p>
// 4th


<p>21{{ "minutes" | transloco : { minutes: 21 } }}</p>
// 21st

Interpolation

To reuse the value passed to the pipe to determine the translation used, we can use the # character, which will be substituted with the passed-in value at runtime.

{
 "minutesOrdinal": "{minutes, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}",
}
<p>{{ "minutes" | transloco : { minutes: 1 } }}</p>
// 1st

Interpolation in a sentence

In some cases, we are not just translating a single word, but rather a longer string, and only a part of it needs to be dynamically interpolated.

{
"applesInBasket": "I have {apples, plural, one {# apple} other {# apples}} in the basket.",
}
<p>{{ "applesInBasket" | transloco : { apples: 1 } }}</p>
// I have 1 apple in the basket.

<p>{{ "applesInBasket" | transloco : { apples: 5 } }}</p>
// I have 5 apples in the basket.

Explicit handling of certain values

Some values require special translation. The plugin allows us to explicitly specify a custom translation for one or more of those values if needed. In the following example, we explicitly handle zero.

{
"applesExactCount": "I {apples, plural, =0 {don't have apples} one {have # apple} other {have # apples}} in the basket.",
}
<p>{{ "applesExactCount" | transloco : { apples: 0 } }}</p>
// I don't have apples in the basket.

<p>{{ "applesExactCount" | transloco : { apples: 1 } }}</p>
// I have 1 apple in the basket.

<p>{{ "applesExactCount" | transloco : { apples: 5 } }}</p>
// I have 5 apples in the basket.