ngx-translate TranslateService API Reference
Inject TranslateService using Angular’s inject() function:
import { inject } from '@angular/core';import { TranslateService } from '@ngx-translate/core';
export class MyComponent { private translate = inject(TranslateService);}In v18 several language fields are now signals. Read them by calling the
signal as a function (e.g. translate.currentLang()). Signal reads inside
templates, computed(), and effect() are tracked automatically; no manual
subscriptions needed.
- currentLang:
Signal<Language | null>, current language as a reactive signal - fallbackLang:
Signal<Language | null>, fallback language as a reactive signal - isLoading:
Signal<boolean>,truewhile a language load is in flight
- use: set the current language and load it if needed
- setFallbackLang: set and load the fallback language
- getFallbackLang: non-reactive snapshot of the fallback language
- getCurrentLang: non-reactive snapshot of the current language
- getLangs: list loaded/registered languages
- addLangs: register language codes without loading them
- translate: returns a
Signal<Translation>(also available as standalonetranslate()) - stream:
Observablethat re-emits on language / translation changes - instant: synchronous lookup
- get: one-shot
Observableonce translations are loaded - getStreamOnTranslationChange: observable that re-emits on translation changes
- Per-call
langparameter: applies totranslate,get,instant,stream,getStreamOnTranslationChange,getParsedResult
- getBrowserCultureLang: e.g.
"de-DE" - getBrowserLang: e.g.
"de"
- set: set a single translation key
- setTranslation: set a full language object (passes through the compiler)
- setCompiledTranslation: set an already-compiled language object (bypasses the compiler)
- getTranslations: read the stored translation object for a language
- reloadLang: reset and re-fetch a language
- resetLang: remove a language from the store
- getParent: returns the parent service, or
nullfor a root / isolated subtree root - getRoot: returns the topmost service in the chain (root of an isolated subtree, or top-level root)
- onLangChange: emits when the current language changes
- onFallbackLangChange: emits when the fallback language changes
- onTranslationChange: emits when a translation object changes
- onTranslationRefresh: merged stream of the three events relevant to displayed text
addLangs(languages: Language[]): voidRegisters language codes without invoking the loader. Use it when you want a
language to appear in getLangs() ahead of an actual load.
readonly currentLang: Signal<Language | null>The currently active language as a reactive Signal. Read it by calling
the signal as a function:
const lang: string | null = translate.currentLang();In templates and computed() / effect(), Angular tracks the read
automatically:
<p>Current language: {{ translate.currentLang() }}</p>isGerman = computed(() => this.translate.currentLang() === 'de');
constructor() { effect(() => { console.log('Language switched to', this.translate.currentLang()); });}For a non-reactive snapshot, use getCurrentLang().
readonly fallbackLang: Signal<Language | null>The fallback language as a reactive Signal, sibling to
currentLang. Read by calling the signal:
const fallback = translate.fallbackLang();For a non-reactive snapshot, use getFallbackLang().
get isLoading(): Signal<boolean>A reactive Signal<boolean> that is true while one or more language loads are
in flight at this service or any of its ancestors in the service hierarchy.
Designed for spinners and “language switching…” indicators during
use() and setFallbackLang().
Read by calling the signal:
const busy: boolean = translate.isLoading();In a template:
@if (translate.isLoading()) { <app-spinner />}Loading propagates downward, not upward:
- A load triggered at the root marks the root and all descendants as loading. App-shell spinners (injected at root) cover language switches that initiate anywhere in the tree.
- A load triggered at a child (e.g. a lazy-route bootstrap fetching its own translations) marks only that child’s subtree. Siblings and ancestors are unaffected — sibling subtrees that finished loading earlier do not flip back to loading.
Drive a spinner by reading isLoading from the service injected at the scope
where the spinner should live: root for an app-shell spinner, the nearest
child for a local spinner inside a lazy-loaded subtree.
See also Concepts → Hierarchical Services and the Show a loading indicator during language switch recipe.
get( key: string | string[], interpolateParams?: InterpolationParameters, lang?: Language,): Observable<Translation>
Translationis a union covering both output shapes: a single key yields astring; an array of keys yields aTranslationObject(keyed by each input key).
Retrieves the translation(s) for the specified key(s). The Observable emits
once translations have finished loading, then completes.
key: a single key or an array of keys.interpolateParams(optional): interpolation values.lang(optional, new in v18): look up translations in a specific language, bypassing the current/fallback chain. See Per-calllangparameter.
- Single key → emits a
Translation. - Array of keys → emits an object
{ [key]: Translation }. - Missing key → returns the key itself unless a fallback resolves it.
translate.get('HELLO').subscribe((res) => console.log(res));// 'Hello'
translate.get(['HELLO', 'WELCOME']).subscribe((res) => console.log(res));// { HELLO: 'Hello', WELCOME: 'Welcome' }
translate.get('WELCOME_USER', { username: 'John' }).subscribe((res) => console.log(res));// 'Welcome, John!'
// Per-call lang (new in v18): look up in German regardless of current langtranslate.get('HELLO', undefined, 'de').subscribe((res) => console.log(res));// 'Hallo'getBrowserCultureLang(): Language | undefinedReturns the browser’s full culture language code (e.g. "en-US"), or
undefined if it can’t be determined.
getBrowserLang(): Language | undefinedReturns the browser’s language without region (e.g. "de"), or undefined.
getCurrentLang(): Language | nullNon-reactive snapshot of the current language. Returns null before any
language is set. For reactive reads use currentLang.
getFallbackLang(): Language | nullNon-reactive snapshot of the fallback language. Returns null if none is set.
For reactive reads use fallbackLang.
getLangs(): readonly Language[]Returns the list of currently registered languages. The list grows when
use(), setFallbackLang(),
setTranslation(), or addLangs() is called.
getParent(): ITranslateService | nullReturns the parent service this one inherits translations from. Returns null
when the service is the terminus of its fallback chain (i.e. it is the
top-level root or the root of an isolated subtree, a nested
provideTranslateService()).
Use it to introspect the chain at runtime without reaching into protected fields:
let svc: TranslateService | null = inject(TranslateService);while (svc) { console.log(svc); svc = svc.getParent();}See Concepts → Hierarchical Services.
For the topmost service in the chain (skipping the walk), use
getRoot().
getRoot(): ITranslateServiceReturns the topmost service in this service’s hierarchy — the terminus of the
getParent() chain. For an isolated subtree (a nested
provideTranslateService()), returns the subtree’s own root, not the outer
top-level root.
A root service returns itself. Equivalent to walking getParent() until it
returns null, but provided as a convenience:
// Write a translation globally from a child component.const root = inject(TranslateService).getRoot();root.set('GLOBAL.MESSAGE', 'Hallo Welt!', 'de');For arbitrary-depth chains, prefer getRoot() over walking getParent()
manually — it terminates correctly at isolation boundaries.
getStreamOnTranslationChange( key: string | string[], interpolateParams?: InterpolationParameters, lang?: Language,): Observable<Translation>Like get() but emits a new value whenever translations change
(setTranslation(), set(), reloadLang()). Does not emit on plain language
changes. Use stream() for that.
lang is the same per-call language override documented in
Per-call lang parameter.
const sub = translate .getStreamOnTranslationChange('HELLO') .subscribe((res) => console.log(res));
const subMulti = translate .getStreamOnTranslationChange(['HELLO', 'WELCOME']) .subscribe((res) => console.log(res));
const subParams = translate .getStreamOnTranslationChange('WELCOME_USER', { username: 'John' }) .subscribe((res) => console.log(res));
sub.unsubscribe();getTranslations(language: Language): DeepReadonly<InterpolatableTranslationObject>Returns the full stored translation object for a language as a deep-readonly
snapshot. Useful for inspecting what has been loaded into the store. The
underlying state is immutable; re-call getTranslations(lang) after a write
to see updates.
const en = translate.getTranslations('en');console.log(en.HELLO); // 'Hello'instant( key: string | string[], interpolateParams?: InterpolationParameters, lang?: Language,): TranslationSynchronous lookup. Returns the key itself if translations aren’t loaded yet.
-
key: single key or array. -
interpolateParams(optional): interpolation values. -
lang(optional, new in v18): per-call language override. See Per-calllangparameter. When provided,instant()bypasses the current/fallback chain and reads from that language directly. If the language hasn’t been loaded, ngx-translate emits a one-shotconsole.warnper unloaded language:@ngx-translate/core: instant() called with lang="de" but no translationsare loaded for that language. Returning the key as fallback. Load withuse("de") or setTranslation("de", ...) first.
const res = translate.instant('HELLO');// 'Hello'
translate.instant(['HELLO', 'WELCOME']);// { HELLO: 'Hello', WELCOME: 'Welcome' }
translate.instant('WELCOME_USER', { username: 'John' });// 'Welcome, John!'
// Per-call langtranslate.instant('HELLO', undefined, 'fr');// 'Bonjour'get onTranslationRefresh(): Observable<void>Convenience observable that emits whenever displayed translations might need to refresh. Merges:
onLangChange(the current language changed)onFallbackLangChange(the fallback language changed)onTranslationChangefiltered to events for the current or fallback language
For child services, the parent’s onTranslationRefresh is also merged in, so
a child subscriber sees refreshes that bubble down from the root.
Use it when a single stream is preferable to subscribing to all three event observables separately. The pipe and directive use it internally.
translate.onTranslationRefresh.subscribe(() => { // re-render or re-fetch something that depends on translated text});reloadLang(lang: string): Observable<InterpolatableTranslationObject>Calls resetLang() and then re-fetches the language via the
configured loader.
resetLang(lang: Language): voidRemoves the stored translations for a language. Call use() or
reloadLang() afterwards to repopulate.
set(key: string, translation: string | TranslationObject, lang?: Language): voidSets a single translation value, compiling it through the configured
TranslateCompiler.
key: dot-separated path (e.g.hello.world).translation: the value (or sub-tree).lang(optional): defaults to the current language.
translate.set('HELLO.WORLD', 'Hallo World!');translate.set('HELLO.WORLD', 'Hallo Welt!', 'de');setCompiledTranslation( lang: Language, translations: InterpolatableTranslationObject, shouldMerge?: boolean,): voidNew in v18. Stores a translation object that is already in its
interpolator-ready form, typically the output of a build-time compilation
step that emitted interpolation functions. Unlike setTranslation,
it bypasses the configured TranslateCompiler.
lang: language code.translations: already-compiled object (may containFunctioninterpolators).shouldMerge(defaultfalse): iftrue, deep-merges with existing translations for that language; otherwise replaces.
import precompiled from './precompiled-en';
translate.setCompiledTranslation('en', precompiled);// later, merge feature-specific compiled translations:translate.setCompiledTranslation('en', featurePrecompiled, true);Use setTranslation for raw source translations that still
need to go through the compiler.
setFallbackLang(lang: string): Observable<InterpolatableTranslationObject>Sets the fallback language and triggers a load if needed. Emits an
onFallbackLangChange event on completion. Returns an observable that
completes when the load finishes.
translate.setFallbackLang('en').subscribe(() => { console.log('Fallback set to English');});setTranslation( lang: Language, translations: TranslationObject, shouldMerge?: boolean,): voidSets the translation object for a language, passing it through the configured
TranslateCompiler. Updates the list of
known languages (visible via getLangs).
lang: language code.translations: raw translation object.shouldMerge(defaultfalse): iftrue, deep-merges with the existing language object; otherwise replaces.
stream( key: string | string[], interpolateParams?: InterpolationParameters, lang?: Language,): Observable<Translation>Returns an Observable that emits a translation, then re-emits whenever the
language changes (onLangChange). With lang provided, it also re-emits when
that specific language’s translations are reloaded.
Does not complete; unsubscribe when no longer needed.
lang is the same per-call language override documented in
Per-call lang parameter.
const sub = translate.stream('HELLO').subscribe((res) => console.log(res));sub.unsubscribe();translate( key: string | string[] | (() => string | string[]), params?: object | (() => object | undefined), lang?: Language | (() => Language | undefined),): Signal<Translation | TranslationObject>New in v18. Returns a Signal<Translation> that updates automatically on
language changes, translation reloads, and input signal changes, with no
subscriptions or cleanup. Each parameter accepts a plain value, an arrow
function, or a Signal (Signal<T> is callable, so it counts as a function).
Also exported as a standalone translate() function
that calls TranslateService.translate(...) from an injection context. Use
that form for component field initializers.
greeting = this.translate.translate('HELLO');labels = this.translate.translate(['SAVE', 'CANCEL']);dynamic = this.translate.translate(() => this.model().currentKey);fromSig = this.translate.translate(this.keySignal, this.paramsSignal);use(lang: string): Observable<InterpolatableTranslationObject>Switches the current language. Loads the language if not already loaded.
Returns an observable that completes when the load finishes; the current
language is updated deterministically. When several use() calls happen in
quick succession, the most recent call wins regardless of which load finishes
first.
Subscribers to stream(), currentLang (signal),
or onLangChange will receive updates.
translate.use('fr').subscribe(() => { console.log('Current language is now French.');});If the loader throws or the returned observable errors, use() rolls back
currentLang to whatever it was before the call. The service never reports a
language whose translations it does not actually have loaded.
Subscribe to the error to surface the failure to the user — for example, show a toast and let them retry:
translate.use('fr').subscribe({ next: () => { /* loaded */ }, error: (err) => { // currentLang is unchanged. Safe to re-render against the previous language. console.error('Failed to load French translations', err); },});New in v18. Lookup methods accept an optional lang argument that
bypasses the current/fallback chain and reads from a specific language:
translate(key, params?, lang?): Signal-basedget(key, params?, lang?):Observable, completes onceinstant(key, params?, lang?): synchronousstream(key, params?, lang?):Observable, re-emitsgetStreamOnTranslationChange(key, params?, lang?):Observable, re-emits on translation changesgetParsedResult(key, params?, lang?): protected, same shape
Use it to display a phrase in a fixed language regardless of the active one
(e.g. a brand name that always renders in English), or to look up data while a
language switch is in flight. Pre-load via use(lang) or
setTranslation(lang, ...) to avoid the unloaded-lang console.warn from
instant().
// Always render this label in EnglishenglishLabel = this.translate.translate('LABEL', undefined, 'en');
// One-shot read from a specific languageconst fr = this.translate.instant('TITLE', undefined, 'fr');Emits a LangChangeEvent whenever the current language changes (after the new
language’s translations have finished loading).
| Name | Type | Description |
|---|---|---|
lang | string | The newly active language code. |
translations | InterpolatableTranslationObject | The translations for the new language. |
Emits a FallbackLangChangeEvent whenever the fallback language changes.
| Name | Type | Description |
|---|---|---|
lang | string | The newly set fallback language code. |
translations | InterpolatableTranslationObject | The translations for the fallback language. |
Emits a TranslationChangeEvent whenever a translation object changes for any
language (via setTranslation, set, reloadLang).
| Name | Type | Description |
|---|---|---|
lang | string | The language whose translations changed. |
translations | InterpolatableTranslationObject | The updated translations. |
See onTranslationRefresh above: a merged stream of
the three events relevant to displayed text.
The four plugin slots on provideTranslateService() and
provideChildTranslateService() (loader, compiler, parser,
missingTranslationHandler) accept several shapes: a bare class, a bare
factory function, the matching provideTranslate* helper, or an explicit
Angular Provider object. Bare classes and factories are auto-wrapped
internally so they register under the correct DI token.
When you pass a bare class, ngx-translate emits a one-time console.warn per
slot:
@ngx-translate/core: "<field>" received a bare class (<ClassName>);auto-wrapping with <helperName>(). For clarity, prefer<field>: <helperName>(<ClassName>).For example, provideTranslateService({ missingTranslationHandler: MyHandler })
prints:
@ngx-translate/core: "missingTranslationHandler" received a bare class (MyHandler);auto-wrapping with provideMissingTranslationHandler(). For clarity, prefermissingTranslationHandler: provideMissingTranslationHandler(MyHandler).Your app keeps working; the warning is informational. Bare factory functions
(e.g. loader: () => new MyLoader()) pass through silently; they are the
documented compact form.
Why this exists: in v17 a bare class registered under its own token instead of
the plugin token (TranslateLoader / etc.), so the override was silently
absent and the default plugin was used instead. v18 closes that footgun by
recognising the bare-class shape and wrapping it for you.
The cleanest fix is to wrap explicitly:
// Warns:provideTranslateService({ missingTranslationHandler: MyHandler })
// Silent and explicit:provideTranslateService({ missingTranslationHandler: provideMissingTranslationHandler(MyHandler),})Removed in v18. Use get(), instant(), or
getTranslations(lang) to read stored translations.
setDefaultLang / getDefaultLang / defaultLang / onDefaultLangChange
Section titled “setDefaultLang / getDefaultLang / defaultLang / onDefaultLangChange”Removed in v18. These were deprecated v17 aliases. Use the fallback
equivalents:
| v17 | v18 |
|---|---|
setDefaultLang(lang) | setFallbackLang(lang) |
getDefaultLang() | getFallbackLang() |
defaultLang (getter) | fallbackLang signal |
onDefaultLangChange | onFallbackLangChange |
Removed in v18. Use getLangs().