Skip to content

How to Write a Custom Loader for ngx-translate

If you want to write your own loader, you need to create a class that extends TranslateLoader. The only required method is getTranslation that must return an Observable. If your loader is synchronous, just use of() from RxJS to create an observable from your static value.

To implement your own loader, create a class that extends the TranslateLoader abstract class and implements the getTranslation() method.

Here’s an example of a custom loader that loads translations from local JSON files:

import { Injectable } from '@angular/core';
import { TranslateLoader, TranslationObject } from '@ngx-translate/core';
import { Observable, of } from 'rxjs';
// Import your translation files
import enTranslations from '../../public/i18n/en.json';
import deTranslations from '../../public/i18n/de.json';
import frTranslations from '../../public/i18n/fr.json';
@Injectable()
export class JsonFileLoader extends TranslateLoader {
private translations: { [key: string]: TranslationObject } = {
'en': enTranslations,
'de': deTranslations,
'fr': frTranslations
};
getTranslation(lang: string): Observable<TranslationObject> {
// Return the imported translations for the requested language
const translation = this.translations[lang];
if (translation) {
return of(translation);
}
// Fallback to empty object if language not found
return of({});
}
}

The recommended approach in v18 is to use the provideTranslateLoader() function:

app.config.ts
import {provideTranslateService, provideTranslateLoader} from "@ngx-translate/core";
import {JsonFileLoader} from './json-file-loader';
export const appConfig: ApplicationConfig = {
providers: [
...
provideTranslateService({
loader: provideTranslateLoader(JsonFileLoader),
})
],
};

If your loader needs services from Angular DI (like HttpClient), use the factory form of provideTranslateLoader() together with inject():

app.config.ts
import { ApplicationConfig, inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { provideHttpClient } from "@angular/common/http";
import {
provideTranslateService,
provideTranslateLoader,
} from "@ngx-translate/core";
import { MyHttpLoader } from "./my-http-loader";
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideTranslateService({
loader: provideTranslateLoader(
() => new MyHttpLoader(inject(HttpClient), "/i18n/"),
),
fallbackLang: "en",
}),
],
};

Signal-aware DI runs inside the factory, so inject() calls work the same as in component constructors.

Imprint Privacy