🎸 Using MessageFormat with Transloco
Transloco, an Angular Internationalization Library, was released recently (2019-08-16), with the tagline "Angular Internationalization Done Right". After playing about with the library, it's very clear to see that it greatly simplifies i18n within Angular applications, providing multiple methods to use it within your templates:
- Structural Directive
- Attribute Directive
- Pipe
The most performant of the above methods is the Structural Directive approach as it opens only one subscription for your template. You can find out more about incorporating Transloco in their docs.
However, it soon became apparent that the library did not support messageformat out of the box. This could have been a real deal breaker for us, and for other companies that use messageformat
to handle pluralization and gender in applications. If those phrases are new to you, have you encountered any of the following:
return mins + mins === 1 ? ' minute' : ' minutes' + ' ago';
let pronoun = 'They';
if (user.gender === 'male') {
pronoun = 'He';
} else if (user.gender === 'female') {
pronoun = 'She';
}
return `${pronoun} went to the shop.`;
Doing this every time we need to handle plurals and genders can get tedious, to the point we may put these into their own methods or services to reuse them. But what if we can remove this logic from our codebase altogether? What if we need to support multiple languages, will we need to add additional logic to return the correct pronoun for the active language?
No. Rather, we should let our translation files handle this for us! I recently made a PR to the Transloco library to add support for messageformat
. For now, it will be apart of Transloco >= 1.1.1, however there are plans to move this functionality into a plugin, as not all users may want it.
Below I will show you how to setup and use messageformat
with Transloco.
🔧 Prerequisites
Ensure you have the Angular CLI installed globally. If you do not, run the following command:
npm install -g @angular/cli
If you do not have an application that is currently being developed, create a new one using the command:
ng new <application-name>
🔨 Setup
If you haven't already installed Transloco, first, add it using the ng add @ngneat/transloco
command. This should install the required packages and scaffold the required files for Transloco
to function.
You can find more on installing Transloco here.
To use messageformat
we need to tell Transloco to use the MessageFormatTranspiler
rather than the DefaultTranspiler
. To do this, open your app.module.ts
and the following:
import { TRANSLOCO_TRANSPILER, MessageFormatTranspiler } from '@ngneat/transloco';
In the providers array of the @NgModule
@NgModule({
providers: [
...,
{ provide: TRANSLOCO_PROVIDER, useClass: MessageFormatTranspiler }
]
})
This will allow Transloco to correctly interpret messageformat
formatted strings in your translation files.
🚀 Usage
After the setup, using messageformat is very simple. You can now do the following within your translation files:
en.json
{
"noParams": "Hello - english",
"params": "The following {{ value }} was replaced by Transloco - english",
"plural": "{count, plural, =0 {no results} one {one result} other {# results}} - english",
"gender": "{gender, select, male {he} female {she} other {they}} went to the shop - english"
}
es.json
{
"noParams": "Hello - spanish",
"params": "The following {{ value }} was replaced by Transloco - spanish",
"plural": "{count, plural, =0 {no results} one {one result} other {# results}} - spanish",
"gender": "{gender, select, male {he} female {she} other {they}} went to the shop - spanish"
}
In your templates:
Structural Directive Approach
<ng-container *transloco="let t">
<ul>
<li>{{ t.noParams }}</li>
<li>{{ t.params | translocoParams: {value: "word" } }}</li>
<li>{{ t.plural | translocoParams: {count: 2} }}</li>
<li>{{ t.plural | translocoParams: {count: 1} }}</li>
<li>{{ t.gender | translocoParams: {gender: "male"} }}</li>
<li>{{ t.gender | translocoParams: {gender: ""} }}</li>
</ul>
</ng-container>
Attribute Directive Approach
<ul>
<li><span transloco="noParams"></span> }}</li>
<li><span transloco="params" [translocoParams]="{value: 'word'}"></span></li>
<li><span transloco="plural" [translocoParams]="{count: 2}"></span></li>
<li><span transloco="plural" [translocoParams]="{count: 1}"></span></li>
<li><span transloco="gender" [translocoParams]="{gender: 'male'}"></span></li>
<li><span transloco="gender" [translocoParams]="{gender: ''}"></span></li>
</ul>
Pipe Approach
<ul>
<li>{{ 'noParams' | transloco }}</li>
<li>{{ 'params' | transloco: {value: "word" } }}</li>
<li>{{ 'plural' | transloco: {count: 2} }}</li>
<li>{{ 'plural' | transloco: {count: 1} }}</li>
<li>{{ 'gender' | transloco: {gender: "male"} }}</li>
<li>{{ 'gender' | transloco: {gender: ""} }}</li>
</ul>
🎉 Results
Now, whichever approach you choose, when you run your app, the output will be:
When language is en
:
Hello - english
The following word was replaced by Transloco - english
2 results - english
1 result - english
He went to the shop - english
They went to the shop - english
When language is es
:
Hello - spanish
The following word was replaced by Transloco - spanish
2 results - spanish
1 result - spanish
He went to the shop - spanish
They went to the shop - spanish
🍻 Conclusion
As you can see from above, using the MessageFormatTranspiler with Transloco can drastically reduce the amount of logic in your codebase around grammar relating to pluralization and genders. It makes i18n much easier to implement as you can simply give your en.json
file to your translation team and they can provide translations for all identifiers. These translations can be added, removed and maintained without affecting the business logic of your application!
If you haven't already looked at Transloco you definitely should. It's i18n made easy!
Thanks for reading!
Top comments (0)