ngx-signal-translate
v21.0.4
Published
Signal-first i18n for Angular: lazy-loaded JSON resources, a signal-friendly pipe, and a service with sync, signal, and observable APIs.
Readme
NgxSignalTranslate
Signal-first i18n for Angular: lazy-loaded JSON resources, a signal-friendly pipe, and a service with sync, signal, and observable APIs.
Highlights
- Lazy-load language JSON over HTTP; each language loads once and caches.
- Template pipe that returns a
Signal<string>for ergonomic use in templates. - Service APIs:
translate(sync, signal-friendly),translate$(observable that waits for language load), andsetLanguage. - Placeholder replacement with
string | numberparams.
Install
npm install ngx-signal-translateConfigure
Register the config provider in app.config.ts (or your bootstrap providers). The path is optional; default is the app root.
import { ApplicationConfig } from '@angular/core';
import { provideSignalTranslateConfig } from 'ngx-signal-translate';
export const appConfig: ApplicationConfig = {
providers: [provideSignalTranslateConfig({ path: 'assets/i18n' })],
};Set the initial language (for example in your root component):
import { Component, inject } from '@angular/core';
import { NgxSignalTranslateService } from 'ngx-signal-translate';
@Component({
selector: 'app-root',
template: '<router-outlet />',
})
export class AppComponent {
readonly #translate = inject(NgxSignalTranslateService);
constructor() {
this.#translate.setLanguage('en');
}
}Language files
- Files are JSON, named by language code (e.g.,
en.json,de.json). - Keys map to strings; unknown keys return the key name.
Example en.json:
{
"HELLO": "Hello",
"HELLO_NAME": "Hello {name}"
}Placeholders use {key} syntax and are replaced with TranslateParams values (string or number).
Usage
Template pipe (returns a Signal)
import { Component } from '@angular/core';
import { NgxSignalTranslatePipe } from 'ngx-signal-translate';
@Component({
selector: 'demo-cmp',
standalone: true,
imports: [NgxSignalTranslatePipe],
template: `
<p>{{ ('HELLO' | signalTranslate)() }}</p>
<p>{{ ('HELLO_NAME' | signalTranslate : { name: 'Ada' })() }}</p>
`,
})
export class DemoComponent {}Service in TypeScript
import { Component, computed, effect, inject } from '@angular/core';
import { NgxSignalTranslateService } from 'ngx-signal-translate';
@Component({
selector: 'demo-logic',
template: '{{ greeting() }}',
})
export class DemoLogicComponent {
readonly #translate = inject(NgxSignalTranslateService);
readonly greeting = computed(() => this.#translate.translate('HELLO'));
constructor() {
this.#translate.setLanguage('en');
effect(() => {
// Runs whenever language resources change
console.log(this.#translate.translate('HELLO_NAME', { name: 'Ada' }));
});
this.#translate.translate$('HELLO').subscribe(console.log);
}
}Behavior notes
translatereturns the key if the language or key is missing.translate$waits for the language to be selected and loaded before emitting.- Language files load once per language; failed loads resolve to empty resources and also fall back to returning the key.
