Son astuce pour mieux se former

Plonge dans une interview inspirante et condensée de Gérôme Grignon, développeur frontend passionné et figure incontournable de la communauté Angular francophone.

Dans cet échange, Gérôme partage son parcours, ses conseils d'apprentissage, sa vision d'Angular et sa réflexion sur l'usage de l'IA dans le développement web.

Skip to content

Vous souhaitez recevoir de l'aide sur ce sujet ? rejoignez la communauté Angular.fr sur Discord.

Internationaliser votre application avec ngx-translate 🌍 ​

L'internationalisation (i18n) consiste à adapter votre application pour qu'elle puisse être utilisée dans différentes langues. Imaginez que vous avez créé une application de gestion d'utilisateurs en français, et que vous souhaitez maintenant la rendre accessible à des utilisateurs anglophones, hispanophones ou dans d'autres langues. Au lieu de créer une version complètement séparée de votre application pour chaque langue, vous pouvez utiliser ngx-translate pour gérer toutes les traductions de manière centralisée.

Pensez à ngx-translate comme à un dictionnaire multilingue pour votre application : vous définissez une clé (comme "welcome.message") et vous associez différentes traductions selon la langue choisie. Quand l'utilisateur change de langue, toutes les clés sont automatiquement remplacées par leurs traductions correspondantes.

Dans ce tutoriel, nous allons voir comment installer, configurer et utiliser ngx-translate dans une application Angular moderne.

Installation ​

Pour commencer, nous devons installer les packages nécessaires :

bash
npm install @ngx-translate/core @ngx-translate/http-loader
  • @ngx-translate/core : Le package principal qui contient le service de traduction
  • @ngx-translate/http-loader : Un loader qui permet de charger les fichiers de traduction depuis des fichiers JSON via HTTP

Configuration de l'application ​

Une fois les packages installés, nous devons configurer ngx-translate dans notre application. Nous allons modifier le fichier app.config.ts pour ajouter les providers nécessaires.

Pour charger ngx-translate dans une application Angular moderne, nous utilisons les fonctions provideTranslateService et provideTranslateHttpLoader. Cette approche est alignée avec les fonction-based providers d'Angular et fonctionne parfaitement avec les composants standalone.

Voici comment configurer ngx-translate avec le HttpLoader pour charger les traductions depuis des fichiers JSON :

ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { provideTranslateService } from '@ngx-translate/core';
import { provideTranslateHttpLoader } from '@ngx-translate/http-loader';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(),
    provideTranslateService({
      lang: 'fr',
      fallbackLang: 'en',
      loader: provideTranslateHttpLoader({
        prefix: './assets/i18n/',
        suffix: '.json'
      })
    })
  ]
};

Dans cette configuration :

  • provideTranslateService : Configure le service de traduction avec les paramètres principaux
    • lang : La langue par dĂ©faut de l'application (ici 'fr' pour français)
    • fallbackLang : La langue de secours utilisĂ©e si une traduction est manquante (ici 'en' pour anglais)
  • provideTranslateHttpLoader : Configure le loader HTTP pour charger les fichiers de traduction
    • prefix : Le prĂ©fixe du chemin vers les fichiers de traduction (ici ./assets/i18n/)
    • suffix : L'extension des fichiers de traduction (ici .json)

Cette configuration chargera automatiquement le fichier ./assets/i18n/fr.json pour la langue française, et ./assets/i18n/en.json pour l'anglais.

Avantages de cette approche

Cette nouvelle syntaxe avec provideTranslateService est préférée car :

  • Elle est alignĂ©e avec les fonction-based providers d'Angular moderne
  • Elle fonctionne nativement avec les composants standalone
  • Elle est plus simple et plus lisible que l'ancienne mĂ©thode avec TranslateModule.forRoot()
  • Elle ne nĂ©cessite pas d'utiliser importProvidersFrom

Création des fichiers de traduction ​

Maintenant, créons les fichiers de traduction. Nous allons créer un dossier assets/i18n/ et y placer nos fichiers JSON pour chaque langue.

Créons d'abord le fichier pour le français (fr.json) :

json
{
  "welcome": {
    "title": "Bienvenue",
    "message": "Bienvenue dans notre application de gestion d'utilisateurs",
    "description": "Gérez facilement vos utilisateurs"
  },
  "user": {
    "name": "Nom",
    "email": "Email",
    "username": "Nom d'utilisateur",
    "actions": {
      "create": "Créer un utilisateur",
      "edit": "Modifier",
      "delete": "Supprimer",
      "save": "Enregistrer"
    }
  },
  "common": {
    "loading": "Chargement...",
    "error": "Une erreur est survenue",
    "success": "Opération réussie"
  }
}

Et le fichier pour l'anglais (en.json) :

json
{
  "welcome": {
    "title": "Welcome",
    "message": "Welcome to our user management application",
    "description": "Manage your users easily"
  },
  "user": {
    "name": "Name",
    "email": "Email",
    "username": "Username",
    "actions": {
      "create": "Create a user",
      "edit": "Edit",
      "delete": "Delete",
      "save": "Save"
    }
  },
  "common": {
    "loading": "Loading...",
    "error": "An error occurred",
    "success": "Operation successful"
  }
}

Organisation des traductions

Organisez vos traductions de manière hiérarchique avec des objets imbriqués. Cela permet de regrouper les traductions par fonctionnalité (comme "welcome", "user", "common") et facilite la maintenance.

Utilisation dans les composants ​

Pour utiliser les traductions dans un composant, nous devons injecter le service TranslateService et utiliser le pipe translate dans le template.

Utilisation avec le pipe translate ​

La méthode la plus simple est d'utiliser le pipe translate directement dans le template :

ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';

@Component({
  selector: 'app-welcome',
  standalone: true,
  imports: [CommonModule, TranslateModule],
  template: `
    <div class="welcome">
      <h1>{{ 'welcome.title' | translate }}</h1>
      <p>{{ 'welcome.message' | translate }}</p>
      <p>{{ 'welcome.description' | translate }}</p>
    </div>
  `
})
export class WelcomeComponent {}

Utilisation avec le service TranslateService ​

Pour une utilisation plus avancée, notamment pour changer la langue dynamiquement, nous pouvons utiliser le service TranslateService :

ts
import { Component, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-language-switcher',
  standalone: true,
  imports: [CommonModule, TranslateModule],
  template: `
    <div class="language-switcher">
      <button (click)="switchLanguage('fr')">Français</button>
      <button (click)="switchLanguage('en')">English</button>
      <p>{{ 'common.loading' | translate }}</p>
    </div>
  `
})
export class LanguageSwitcherComponent {
  // Injection du service TranslateService pour gérer les traductions
  private translateService = inject(TranslateService);

  /**
   * Change la langue de l'application
   * Cette méthode met à jour la langue courante et recharge les traductions
   * @param lang - Le code de la langue (ex: 'fr', 'en')
   */
  switchLanguage(lang: string) {
    this.translateService.use(lang);
  }
}

Utilisation avec des paramètres ​

Parfois, vous voulez insérer des valeurs dynamiques dans vos traductions. Par exemple, afficher le nom d'un utilisateur dans un message. Voici comment procéder :

Fichier de traduction (fr.json) :

json
{
  "user": {
    "greeting": "Bonjour {{name}} !",
    "itemsCount": "Vous avez {{count}} élément(s)"
  }
}

Dans le composant :

ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';

@Component({
  selector: 'app-user-greeting',
  standalone: true,
  imports: [CommonModule, TranslateModule],
  template: `
    <div>
      <p>{{ 'user.greeting' | translate: {name: userName} }}</p>
      <p>{{ 'user.itemsCount' | translate: {count: items.length} }}</p>
    </div>
  `
})
export class UserGreetingComponent {
  userName = 'Jean';
  items = [1, 2, 3];
}

Utilisation dans les services ​

Vous pouvez également utiliser le service TranslateService dans vos services pour obtenir des traductions programmatiquement :

ts
import { inject, Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class NotificationService {
  // Injection du service de traduction pour accéder aux traductions dans le service
  private translateService = inject(TranslateService);

  /**
   * Affiche un message de succès traduit
   * Cette méthode récupère la traduction de la clé 'common.success' et l'affiche
   */
  showSuccess(): void {
    this.translateService.get('common.success').subscribe((translation: string) => {
      console.log(translation); // Affiche "Opération réussie" en français ou "Operation successful" en anglais
    });
  }

  /**
   * Récupère une traduction avec des paramètres
   * @param key - La clé de traduction
   * @param params - Les paramètres à insérer dans la traduction
   * @returns Un Observable contenant la traduction
   */
  getTranslation(key: string, params?: any): Observable<string> {
    return this.translateService.get(key, params);
  }
}

Gestion du changement de langue ​

Pour détecter quand la langue change, vous pouvez vous abonner à l'Observable onLangChange du service :

ts
import { Component, inject, OnInit, OnDestroy } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-language-aware',
  standalone: true,
  template: `
    <div>
      <p>Langue actuelle : {{ currentLang }}</p>
    </div>
  `
})
export class LanguageAwareComponent implements OnInit, OnDestroy {
  private translateService = inject(TranslateService);
  private langChangeSubscription?: Subscription;
  currentLang = 'fr';

  /**
   * S'abonne aux changements de langue pour mettre Ă  jour l'interface
   * Cette méthode permet de réagir automatiquement quand l'utilisateur change de langue
   */
  ngOnInit() {
    this.currentLang = this.translateService.currentLang;
    
    this.langChangeSubscription = this.translateService.onLangChange.subscribe((event) => {
      this.currentLang = event.lang;
      console.log('Langue changée vers :', event.lang);
    });
  }

  ngOnDestroy() {
    this.langChangeSubscription?.unsubscribe();
  }
}

Bonnes pratiques ​

Structure des clés de traduction

Utilisez une structure hiérarchique avec des points pour organiser vos clés. Par exemple : feature.section.key plutôt que feature_section_key. Cela améliore la lisibilité et facilite la maintenance.

Fichiers de traduction

Assurez-vous que tous vos fichiers de traduction contiennent les mêmes clés. Si une clé manque dans un fichier, ngx-translate affichera la clé elle-même au lieu de la traduction.

Chargement initial

Avec la configuration dans app.config.ts utilisant provideTranslateService, la langue par défaut est déjà définie (lang: 'fr'). Les traductions sont chargées automatiquement au démarrage de l'application.

Si vous souhaitez changer la langue au démarrage ou détecter la langue du navigateur, vous pouvez le faire dans le AppComponent :

ts
import { Component, inject, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `<router-outlet></router-outlet>`
})
export class AppComponent implements OnInit {
  private translateService = inject(TranslateService);

  ngOnInit() {
    // Optionnel : détecter la langue du navigateur
    const browserLang = navigator.language.split('-')[0];
    const supportedLangs = ['fr', 'en'];
    const langToUse = supportedLangs.includes(browserLang) ? browserLang : 'fr';
    
    // Change la langue si différente de celle configurée par défaut
    this.translateService.use(langToUse);
  }
}

Note : La langue par défaut est déjà configurée dans app.config.ts, donc setDefaultLang n'est généralement pas nécessaire.