Type-safe, reactive Angular i18n library. Lazy-loaded translations, signal-based reactivity, full TypeScript support. Efficient, flexible, and scalable internationalization for Angular projects.
MIT License
ng-intl revolutionizes Angular internationalization with type-safety, IDE intellisense, and signal-based reactivity.
Efficient: Lazy-load bundled translations without HTTP requests.
Type-Safe: Full TypeScript and IDE intellisense support.
Reactive: Signal-based for seamless language switching.
Flexible: Supports both JSON and TypeScript translation files.
Scalable: Ideal for projects of all sizes.
npm install @ng-intl/core
import { provideTranslation } from '@ng-intl/core';
providers: [
provideTranslation({ defaultLanguage: 'en' })
]
import { createScopedTranslation, LanguageService } from '@ng-intl/core';
const { TranslationService, provideScopedTranslation } = createScopedTranslation({
en: () => import('./i18n/en.json'),
es: () => import('./i18n/es'),
fr: () => import('./i18n/fr.json')
});
@Component({
selector: 'app-root',
template: `
<h1>{{ translations()?.appTitle }}</h1>
<p>{{ translations()?.welcomeMessage | interpolate: { username: currentUser } }}</p>
<button (click)="changeLanguage('en')">{{ translations()?.languages.english }}</button>
<button (click)="changeLanguage('es')">{{ translations()?.languages.spanish }}</button>
<button (click)="changeLanguage('fr')">{{ translations()?.languages.french }}</button>
`,
providers: [provideScopedTranslation()]
})
export class AppComponent {
protected readonly translations = inject(TranslationService).translations;
private readonly languageService = inject(LanguageService);
currentUser = 'John Doe';
protected changeLanguage(lang: 'en' | 'es' | 'fr') {
this.languageService.setLanguage(lang);
}
}
The InterpolationPipe
offers versatile string interpolation and localization:
<!-- Simple interpolation -->
{{ 'Hello, {{name}}!' | interpolate:{ name: 'World' } }}
<!-- Select rule -->
{{ 'mySelectRule: "{gender, select, male {He} female {She} other {They}}"' | interpolate:{ gender: 'female' } }}
<!-- Plural rule -->
{{ 'myPluralRule: "{count, plural, =0 {no results} one {1 result} other {# results}}"' | interpolate:{ count: 5 } }}
The pipe supports nested rules, whitespace handling, fallbacks, and various data types, making it suitable for complex internationalization scenarios.
MIT