
Table of content
Want to support more than one language in your app? It may seem like an easy task, but there is a lot you should (and can) do to properly implement multilingual support for your web application.
This guide first walks through an i18n/l10n tutorial for Angular 1, then gives a brief overview of how the same goal is achieved in Angular 2.
Angular 1 i18n/l10n setup
To build a production-ready localized AngularJS app, several modules and tools are typically used:
angular-i18n
angular-dynamic-locale
angular-translate
angular-translate-loader-static-files
LingoHub
Grunt tasks (copy, revisioning, minification)
1. Angular i18n (built-in locale support)
AngularJS supports i18n/l10n for:
date formatting
number formatting
currency formatting
These locale definitions are included in the official AngularJS i18n package.
Copy only needed locale files
Instead of bundling all locales, you copy only the required ones into your app:
locales: {
expand: true,
cwd: 'bower_components/angular-i18n',
src: ['angular-locale_en.js', 'angular-locale_de.js'],
dest: '<%= yeoman.app %>/locales/angular-i18n'
}
Then include a locale file:
<script src="/locales/angular-locale_en.js"></script>
Problem
Only one locale file can be active at a time. Including multiple will overwrite previous ones.
Dynamic locale switching
To support multiple languages dynamically, use:
Configure locale file pattern:
app.config(function(tmhDynamicLocaleProvider) {
tmhDynamicLocaleProvider.localeLocationPattern(
'/locales/angular-i18n/angular-locale_{{locale}}.js'
);
});
Switch language at runtime:
tmhDynamicLocale.set(locale); // 'en', 'de', etc.
This loads the correct locale file asynchronously.
2. Angular Translate (application text i18n)
angular-translate provides translation services, directives, and filters for app text.
JSON-based translations with static file loader
Translation files are structured like:
/locales/en.json
/locales/de.json
Configure loader:
app.config(function($translateProvider) {
$translateProvider.useStaticFilesLoader({
prefix: '/locales/',
suffix: '.json'
});
$translateProvider.preferredLanguage('en')
.fallbackLanguage('en');
$translateProvider.useSanitizeValueStrategy('sceParameters');
});
3. Translation workflow with LingoHub
LingoHub is used to manage translation files:
Typical workflow:
Upload
en.jsonTranslate via editor or professional translators
Download
de.json,fr.json, etc.Or sync directly with GitHub for automation
4. Deployment and cache busting
To avoid serving outdated translations, add versioning to files:
expand: true,
cwd: '<%= yeoman.app %>/locales/',
src: ['*.json'],
dest: '<%= yeoman.dist %>/locales/',
rename: function(dest, src) {
return dest + src.replace('.json', '.<%= revTimestamp %>.json');
}
Then load versioned files:
app.config(function($translateProvider, REVISION) {
var revSuffix = REVISION ? '.' + REVISION : '';
$translateProvider.useStaticFilesLoader({
prefix: '/locales/',
suffix: revSuffix + '.json'
});
});
Angular 2 i18n workflow
Angular 2+ uses a very different approach.
1. Mark translatable text
Add i18n attributes directly in templates:
<h1 i18n>Hello world</h1>
2. Extract translations
Use the extraction tool:
./node_modules/.bin/ng-xi18n
This generates an XLIFF file:
messages.xlf
3. Translate the file
Tools like LingoHub can be used to translate XLIFF files.
Output:
messages.de.xlf
messages.fr.xlf
4. Compile per language (AoT build)
Angular compiles a separate build per language:
./node_modules/.bin/ngc \
--i18nFile=./locale/messages.de.xlf \
--locale=de \
--i18nFormat=xlf
Key concept
You build and deploy a separate version of the application for each supported language.
5. Translation updates
When source text changes:
messages.xlfmust be regeneratedtranslation tools detect added/removed strings
translators update only new content
6. Deployment strategies
Two approaches:
JiT (Just-in-Time) – development mode
AoT (Ahead-of-Time) – production mode (recommended)
AoT benefits:
faster runtime performance
no “flash of untranslated content”
precompiled templates per language
7. Limitations of Angular 2 i18n
Pros
No manual key management
Standardized XLIFF format
Compile-time optimization
Cons
Harder to preserve translation IDs when text changes
Rebuild required per language
Runtime language switching is not native
Runtime language switching?
Not supported in the default Angular 2 i18n workflow.
Angular favors performance over dynamic switching:
Changing language is rare compared to other app interactions.
If runtime switching is needed, alternatives exist such as:
Summary
Angular 1 approach
Runtime translation
JSON files
Dynamic switching possible
Flexible but more manual setup
Angular 2 approach
Compile-time translation
XLIFF files
Separate build per language
Faster and more optimized, but less dynamic
Related articles

Angular i18n update from ng-conf 2015
The LingoHub team described new Angular i18n usage and tooling in this article. Take a look in detail at how this work. Click and read all inside.
$touched is the new $dirty - AngularJS Migration Guide 1.2 to 1.3
Need help to migrate from AngularJS 1.2 to 1.3? Check out our guide. I'll cover key changes and introduce a new feature. Click and learn more ib LingoHub's blog
Improve user experience with these 3 AngularJS directives
AngularJS directives can improve UX by displaying avatars and confirming email addresses. They can also hide optional input fields initially, making them appear upon clicking. Read our described AngularJS directives article in the LingoHub blog