i18n Angular framework using Transifex Native
npm install @transifex/angular
Transifex Native is a full end-to-end, cloud-based localization stack for moderns apps.
Angular library for localizing Angular application using
Transifex Native.
Related packages:
- @transifex/native
- @transifex/cli
Learn more about Transifex Native in the Transifex Developer Hub.
Step1: Create a Transifex Native project in Transifex.
Step2: Grab credentials.
Step3: Internationalize the code using the SDK.
Step4: Push source phrases using the @transifex/cli tool.
Step5: Translate the app using over-the-air updates.
No translation files required.
If you are upgrading from the 1.x.x version, please read this migration guide, as there are breaking changes in place.
Angular 16 is required. If you are using Angular 14 or 15, please use the 6.x.x version of
Transifex Native related packages. If you are using Angular 12 or 13, please use the 5.x.x version of
Transifex Native related packages. If you are using Angular 11, please use the 1.x.x version of
Transifex Native related packages. Other Angular versions are not officially supported at the moment.
Install the library and its dependencies using:
``sh`
npm install @transifex/native @transifex/angular --save
In order to use the TX Native object globally, it is necessary to initialize
the library in the angular application bootstrap, in two locations:
- NgModule initialization
`typescript
@NgModule({
declarations: [
AppComponent,
LoginComponent,
TermsComponent,
HomeComponent,
PrivacyComponent
],
imports: [
AppRoutingModule,
BrowserModule,
// TX Native module declaration
TxNativeModule.forRoot(),
],
providers: [,
],
bootstrap: [AppComponent]
})
`
- Application Boostrap
`typescript
import { Component } from '@angular/core';
import { TranslationService } from '@transifex/angular';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(private translationService: TranslationService) {
// TX Native library intialization
translationService.init({
token: '----- here your TX Native token ------',
});
}
async ngOnInit() {
await this.translationService.getLanguages();
await this.translationService.setCurrentLocale('el');
}
}
`
Component`html
`
Available optional props:
| Prop | Type | Description |
|------------|---------|---------------------------------------------|
| context | String | String context, affects key generation |
| key | String | Custom string key |
| comment | String | Developer comment |
| charlimit | Number | Character limit instruction for translators |
| tags | String | Comma separated list of tags |
| escapeVars | Boolean | If escaping should be applied to ICU variables |
| sanitize | Boolean | Safe render of the HTML result after translation takes place |
| vars | Object | ICU variables to render in the string |
The T component can sanitize the translated result if HTML is involved, using the parameter sanitize, ie this would be possible:
`html`
key="text.agree_message"
[sanitize]=true
[vars]="{ terms_of_services: '' + terms + '',
privacy_policy: '' + privacy + ''
}">
This will render like this in English:
`html`
By proceeding you agree to the terms of service and privacy policy.
And like this in Greek:
`html`
Συνεχίζοντας, αποδέχεστε τους όροι χρήσης και τους πολιτική απορρήτου.
The same block without the sanitize option would be like this, for Greek:
`html`
Συνεχίζοντας, αποδέχεστε τους <a href='terms'>όροι χρήσης</a> και τους <a href='privacy'>πολιτική απορρήτου</a>.
The main thing to keep in mind is that the str property to the T component
must always be a valid ICU message format template.
If it is nested into a `tx-instance` tag, then the `T component` will use the new instance to fetch the translation. Check the TX Instance Component section for more information about additional instances.
Component`html
key="text.copyright"
[inline]=false
comment="This is the current year"
[vars]="{ year: '© 2020' }">
`
UT has the same behaviour as T, but renders source string as HTML inside adiv tag or a span tag if inline property is true. By default this propertyfalse
is set to .
Available optional props:
| Prop | Type | Description |
|------------|---------|---------------------------------------------|
| inline | Boolean | If should wrap the translation with span (true) or with div (false) |
If it is nested into a `tx-instance` tag, then the `UT component` will use the new instance to fetch the translation. Check the TX Instance Component section for more information about additional instances.
serviceThis is the main service exposed from the SDK in order to intialize the TX Native object.
In your bootstrap entry point in the Angular application, you should initialize the SDK, like this:
`typescript
import { Component } from '@angular/core';
import { TranslationService } from '@transifex/angular';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'TX Native Angular Demo';
constructor(private translationService: TranslationService) {
translationService.init({
token: '----- here your TX Native token ------',
});
}
async ngOnInit() {
await this.translationService.getLanguages();
await this.translationService.setCurrentLocale('el');
}
}
`singleton
The translation service is a instance so the initialization will be shared across the whole application.
It keeps also a collection of additional TX Native instances which can be added to the default instance for specific purposes.
Each addional instance should have the following configuration:
`ts`
ITXInstanceConfiguration {
token: string;
alias: string;
controlled: boolean;
}
See the section TX Instance Component for more details.
The additional instances can be added and retrieved using exposed methods `addInstance` and `getInstance`.
The translation service also offers the possibility to retrieve translations that match a given list of tags, this way it's possible to fetch groups of translations in batches, at different times or for lazy loading. This can be achieved using the `fetchTranslations` method.
Exposes the following methods and properties:
| Method | Parameters | Description |
|------------------|------------------|---------------------------------------------------|
| init | config 1 | Initializes the TX Native object |
| setCurrentLocale | locale | Set the current locale in the TX Native object |
| getCurrentLocale | none | Returns the current locale of the TX Native object|
| getLanguages | none | Returns an array of available languages |
| translate | translate params 2 | Returns the translation for a string with given translation params |
| localeChanged | none | Returns an observable for monitoring the locale changed event |
| translationsFetched | none | Returns an observable for monitoring the fetch translations event |
| addInstance | ITXInstanceConfiguration | Returns true if the new TX Native instance was added succesfully and false otherwise |
| getInstance | string | Returns the TX Native instance with the given alias. If the operation is not possible the default one is returned as fallback. |
| fetchTranslations | array | Returns a collection of translations that match a given list of tags. |
(1) Initialization config
`typescript`
export interface ITranslationServiceConfig {
token: string;
cdsHost?: string;
filterTags?: string;
filterStatus?: string;
cache?: () => void;
missingPolicy?: IPolicy;
errorPolicy?: IPolicy;
stringRenderer?: IStringRenderer;
}cache
- , missingPolicy, errorPolicy and stringRenderer are set by default by@transifex/native package but you can provide if you wish custom functions@transifex/native
of your own, or use another policy provided by the package.
Please check the documentation related to this on@transifex/native package here.
(2) Translation params
`typescript`
str: string // string to be translated
params: Record
The params should follow the interface:
`typescript`
export interface ITranslateParams {
_context?: string;
_comment?: string;
_charlimit?: number;
_tags?: string;
_key?: string;
_escapeVars?: boolean;
_inline?: boolean;
sanitize?: boolean;
}
DecoratorThis is a decorator for using inside classes and components in order to have
properties with the translation and used them in code and templates.
An example of use is the following:
`typescript
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { T, TranslationService } from '@transifex/angular';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
// Translations using decorator
@T('Monday', { _key: 'text.monday' })
weekday: string;
@T('terms of service', { _key: 'text.terms_of_service' })
terms: string;
@T('privacy policy', { _key: 'text.privacy_policy' })
privacy: string;
constructor(
private translationService: TranslationService,
private router: Router) {}
login() {
this.router.navigateByUrl('home');
}
}
`
and the use of the properties in the template:
`html`
key="text.agree_message"
[sanitize]=true
[vars]="{ terms_of_services: '' + terms + '',
privacy_policy: '' + privacy + ''
}"
>
An instance configuration can be passed to the decorator in order to use an alternative instance instead of the main TX Native one.
See TX Instance Component for more information.
Example of alternative instance:
`ts
const INSTANCE_CONFIG = {
token: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXX',
alias: 'mycmppage',
controlled: true,
};
@Component({
selector: 'my-component',
templateUrl: './my.component.html',
styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {
@T('My string', { _key: 'text.my_string' }, INSTANCE_CONFIG)
myString: string;
`
PipeYou have available a translate pipe for inline strings translations, the only limitation that it has is that
you cannot translate strings with embedded HTML.
These examples will work:
`html
{{ 'Copyright {year} by Transifex' | translate:{ _key: 'text.copyright' } }}
A paragraph
this example will not work, as it has HTML embedded:
`html
{{ 'A string with HTML embedded' | translate }}
`If it is nested into a
`tx-instance` tag, then the pipe will use the new instance to fetch the translation. Check the TX Instance Component section for more information about additional instances.Language Picker Component
Renders a