DEV Community

Cover image for 🚀 Introducing Transloco: Angular Internationalization Done Right
Netanel Basal
Netanel Basal

Posted on

🚀 Introducing Transloco: Angular Internationalization Done Right

Originally published at netbasal.com

For a while I've been thinking about creating an Angular i18n library, which incorporates some concepts I had in mind.

A couple of weeks ago I was bored 😀, so I decided that's it time to take the bull by the horns and go ahead and create a robust library, chock-full of all the features I'd expect from such a library.

I recruited Shahar Kazaz and Itay Oded to the task; Together, we worked hard over the weeknights, and that's how Transloco was born.

I've also created the ng-neat organization, to hold all my open source libraries. Currently it only holds Transloco, but I also plan to transfer Spectator, ngx-until-destroy, ngx-content-loader, and any future open-source Angular libraries I create.

Let's take a look at what Transloco has to offer.

Install the library using Angular CLI:

ng add @ngneat/transloco

As part of the installation process you'll be presented with questions; Once you answer them, everything you need will automatically be created for you. Let's take a closer look at the generated files.

First, Transloco creates boilerplate files for the requested translations:

assets/i18n/en.json

{
  "hello": "transloco en",
  "dynamic": "transloco {{value}}"
}

assets/i18n/es.json

{
  "hello": "transloco es",
  "dynamic": "transloco {{value}}"
}

Next, it injects the TranslocoModule into the AppModule, and sets some default options for you:

import { TRANSLOCO_CONFIG, TranslocoModule } from '@ngneat/transloco';
import { HttpClientModule } from '@angular/common/http';
import { httpLoader } from './loaders/http.loader';
import { environment } from '../environments/environment';

@NgModule({
  imports: [TranslocoModule, HttpClientModule],
  providers: [
    httpLoader
    {
      provide: TRANSLOCO_CONFIG,
      useValue: {
        prodMode: environment.production,
        listenToLangChange: true,
        defaultLang: 'en'
      }
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Let's explain each one of the config options:

  • listenToLangChange: Subscribes to the language change event, and allows you to change the active language. This is not needed in applications that don't allow the user to change the language in runtime (i.e., from a dropdown), so by setting it to false in these cases, you can save on memory by rendering the view once, and unsubscribing from the language changes event (defaults to false)
  • defaultLang: Sets the default language
  • fallbackLang: Sets the default language/s to use as a fallback
  • failedRetries: How many time should Transloco retry to load translation files, in case of a load failure (defaults to 2)

It also injects the httpLoader into the AppModule providers:

import { HttpClient } from '@angular/common/http';
import { Translation, TRANSLOCO_LOADER, TranslocoLoader } from '@ngneat/transloco';
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class HttpLoader implements TranslocoLoader {
  constructor(private http: HttpClient) {}

  getTranslation(langPath: string) {
    return this.http.get<Translation>(`/assets/i18n/${langPath}.json`);
  }
}

export const httpLoader = { provide: TRANSLOCO_LOADER, useClass: HttpLoader };

The HttpLoader is a class that implements the TranslocoLoader interface. It's responsible for instructing transloco how to load the translation files. It uses Angular HTTP client to fetch the files, based on the given path.

Translation in the Template

Transloco provides three ways to translate your templates:

Using the Structural Directive

This is the recommended approach. It's DRY and efficient, as it creates one subscription per template:

<ng-container *transloco="let t">
  <ul>
    <li>{{ t.home }}</li>
    <li>{{ t.alert | translocoParams: { value: dynamic } }}</li>
  </ul>
</ng-container>

Using the Attribute Directive

<ul>
  <li><span transloco="home"></span></li>
  <li>
    <span transloco="alert" [translocoParams]="{ value: dynamic }"></span>
  </li>
  <li><span [transloco]="key"></span></li>
</ul>

Using the Pipe

<span>{{ 'home' | transloco }}</span> 
<span>{{ 'alert' | transloco: { value: dynamic } }}</span>

Programmatical Translation

Sometimes you may need to translate a key in a component or a service. To do so, you can inject the TranslocoService and use its translate method:

export class AppComponent {
  constructor(private service: TranslocoService) {}

  ngOnInit() {
    this.service.translate('hello');
    this.service.translate('hello', { value: 'world' });
    this.service.translate(['hello', 'key']);
    this.service.translate('hello', params, 'en');
    this.service.translate<T>(translate => translate.someKey);
  }
}

😱 But Wait - There's More!

This was just a taste of Transloco, it also supports:

  • 😴 Lazy Loading
  • 😍 Multiple Languages
  • 🔥 Multiple Fallbacks
  • 🤓 Testing
  • 🦊 Fully customizable

You can find everything you need, along with examples, in our official README file.

Migration from ngx-translate

Transloco provides a schematics command that will help you with the migration process. Check out the comparison table for more information.

Happy translating, and don't forget to show your appreciation by starring!

⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️

Top comments (2)

Collapse
 
carlillo profile image
Carlos Caballero

Hi @netanelbasal !

Thanks for your module. It is very important in the community. I love ngx-translate but I think that there is a gap in angular community that will be occupied by trasloco.

💪⭐

Collapse
 
salimchemes profile image
Salim Chemes

awesome