DEV Community

Cover image for 👨‍💻 Implementing Internationalization (i18n) in Angular
Artem Turlenko
Artem Turlenko

Posted on

👨‍💻 Implementing Internationalization (i18n) in Angular

Developing an application for a global audience requires more than just translating text. It involves internationalization (i18n)—the process of making your app ready for different languages and cultural norms. Angular provides built-in support for i18n, which streamlines the translation process and makes your app accessible to a broader audience. In this post, we’ll explore why i18n matters, how to implement it in Angular, and best practices for multilingual apps.


🔍 Why Internationalization (i18n) Matters

  1. Global Reach: If your app supports multiple languages, you can attract users from different regions.
  2. Better User Experience: Providing localized UI elements and content improves user engagement.
  3. Legal Compliance: In some regions, apps must be available in official languages.
  4. Scalability: Having a robust i18n solution allows you to add more languages easily.

⚡ Key Angular i18n Concepts

  1. Localization (l10n): The process of actually translating and adapting the app content into specific languages.
  2. Translation Files: Files (.xlf, .xlf2, or .json) that store all the translations.
  3. Extracting Messages: Angular CLI provides a command to extract text messages from the code.
  4. Build Configurations: Angular can build multiple language versions of your app.

đź›  Setting Up i18n in Angular

1. Marking Text for Translation

Use Angular’s i18n attribute or inline comments to mark text for translation.

<!-- Simple text -->
<p i18n>Hello world</p>

<!-- Text with a description -->
<p i18n="@@customId: A welcome message displayed to the user">
  Welcome to our Application!
</p>
Enter fullscreen mode Exit fullscreen mode
  • i18n marks the text for extraction.
  • @@customId defines a custom message ID (optional).
  • "A welcome message..." is a description for translators.

2. Extracting Translation Strings

Run the Angular CLI command to extract messages:

ng extract-i18n --output-path src/locale
Enter fullscreen mode Exit fullscreen mode

This command generates an XLIFF file (default is messages.xlf) containing all marked text.

<trans-unit id="customId" datatype="html">
  <source>Welcome to our Application!</source>
  <target></target>
</trans-unit>
Enter fullscreen mode Exit fullscreen mode

3. Creating Translation Files

  • Open the generated .xlf file.
  • Fill the <target> tags with translations.
  • Save the file under a language-specific name, e.g., messages.es.xlf for Spanish.
<trans-unit id="customId" datatype="html">
  <source>Welcome to our Application!</source>
  <target>¡Bienvenido a nuestra aplicación!</target>
</trans-unit>
Enter fullscreen mode Exit fullscreen mode

4. Configuring Angular for Multiple Locales

Update the angular.json file to create multiple build configurations. Each configuration can specify a different locale.

{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "options": {
            "i18nMissingTranslation": "error"
          },
          "configurations": {
            "es": {
              "localize": ["es"],
              "outputPath": "dist/my-app-es"
            },
            "fr": {
              "localize": ["fr"],
              "outputPath": "dist/my-app-fr"
            }
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Make sure your translation files are placed in the src/locale folder and named accordingly (e.g., messages.es.xlf, messages.fr.xlf).

5. Building for Specific Locales

ng build --configuration es
ng build --configuration fr
Enter fullscreen mode Exit fullscreen mode

This generates localized builds in dist/my-app-es and dist/my-app-fr.


🎨 Dynamic Locale Switching

While the default Angular i18n approach builds separate bundles per locale, you can also implement runtime locale switching. However, this often requires:

  • Third-party libraries (e.g., @ngx-translate/core).
  • Custom logic to load translation files on demand.

Why separate builds? For large apps, separate builds may offer better performance for each locale by not bundling all languages. However, if you need on-the-fly language switching, consider using libraries like Transloco or ngx-translate.

import { TranslateService } from '@ngx-translate/core';

constructor(private translate: TranslateService) {
  // Set default language
  translate.setDefaultLang('en');
}

switchLanguage(lang: string) {
  this.translate.use(lang);
}
Enter fullscreen mode Exit fullscreen mode

🏆 Best Practices

  1. Plan for Multiple Locales Early: If you anticipate needing multiple languages, implement i18n from the beginning.
  2. Keep Translations Organized: Use consistent naming conventions for translation files.
  3. Provide Context: Use descriptions in your i18n tags to help translators understand the text.
  4. Handle Pluralization & ICU Messages: Angular’s i18n supports ICU syntax for handling gender, number, and plural forms.
  5. Automate Workflows: Set up CI/CD pipelines to build and deploy multiple locales.

đź’ˇ Common Pitfalls

  • Forgetting to Mark Text: Any unmarked text won’t appear in the translation file.
  • Mismatched IDs: Changing custom message IDs without updating translation files causes conflicts.
  • Hard-Coded Strings in Components: Keep strings in templates; if you must put them in components, mark them properly.
  • Ignoring Plural Rules: Different languages have unique plural forms—leverage ICU messages to address this.

✨ Conclusion

Implementing i18n in Angular ensures your application is accessible to users worldwide, enhancing user experience and satisfying legal or regional requirements. Whether you opt for Angular’s built-in i18n or third-party libraries for dynamic translation, planning for internationalization early on makes your project more versatile and scalable.

💬 What challenges have you faced with i18n in Angular? Let’s discuss in the comments! 🚀

Top comments (2)

Collapse
 
blake_tappestudent_4e648 profile image
Blake Tappe STUDENT

Image description

Collapse
 
blake_tappestudent_4e648 profile image
Blake Tappe STUDENT

I'm only 5
Image description