-
-
Save ocombe/593d21598d988bf6a8609ba5fc00b67e to your computer and use it in GitHub Desktop.
import {TranslateLoader} from "ng2-translate/ng2-translate"; | |
import {Observable} from "rxjs/Observable"; | |
import fs = require('fs'); | |
export class TranslateUniversalLoader implements TranslateLoader { | |
constructor(private prefix: string = 'i18n', private suffix: string = '.json') {} | |
/** | |
* Gets the translations from the server | |
* @param lang | |
* @returns {any} | |
*/ | |
public getTranslation(lang: string): Observable<any> { | |
return Observable.create(observer => { | |
observer.next(JSON.parse(fs.readFileSync(`${this.prefix}/${lang}${this.suffix}`, 'utf8'))); | |
observer.complete(); | |
}); | |
} | |
} |
Thanks, updated
It would be really great if there were something in the core docs mentioning this file. However, how is FS supposed to work from the browser? I've been using BrowserFS to get file access, but it only works for the browser's local storage. Is there something I'm missing for this?
P.S. import {TranslateLoader} from "ng2-translate/ng2-translate"
should be changed to import {TranslateLoader} from "@ngx-translate/core"
to match the new package name.
@elliotwesoff, I was successfully using this code with ng2-translate
, but after upgrading to ngx-translate
I get an error in the terminal, I've posted the issue on StackOverflow.
Should it be sufficient to update only the import
statement? In my case it's not working unfortunately.
@elliotwesoff If you are using webpack, add json loader to load JSON directly.
import en from './i18n/en.json';
Hi everyone, I was trying to handle the universal loader in a more programmatic way, and ended up releasing the universal-loader package on github (https://github.com/fulls1z3/ngx-translate/tree/master/packages/%40ngx-universal/translate-loader) as well as on npm (https://www.npmjs.com/package/@ngx-universal/translate-loader).
It basically accepts the loader for the browser platform as a parameter, and provides the translations to the server platform using fs
.
You can visit the ng-seed/universal for demo usage/instructions.
@ocombe, as a non-contributor, I didn't have chance to create a repo under ngx-translate
. But if you think it would be useful for others, you can fork/copy and amend this package to distribute under ngx-translate
.
how i can use ngx-universal/translate-loader with an angular cli project with universal support
Keep it simple - I'm using @angular/cli
file: src/shared/lang-switcher/custom-translate-loader.ts
import { en } from "assets/i18n/en";
import { srb } from "assets/i18n/srb";
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
export class CustomTranslateLoader implements TranslateLoader {
public getTranslation(lang: string): Observable<any> {
return Observable.create(observer => {
if (lang === 'srb') {
observer.next(srb);
} else {
observer.next(en);
}
observer.complete();
});
}
}
file: src/app/app.module.ts
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader
}
}),
Translation files
file: src/assets/i18n/en.ts
export const en = {
menu: 'Menu',
search: 'Search',
};
file: src/assets/i18n/srb.ts
export const srb = {
menu: 'Meni',
search: 'Pretraži',
};
Hope this will help someone ;-)
any1 had issues with integration and resolved it? can use your help. ngx-translate/core#581
That loader will not work with Angular-cli until Angular teams resolve node modules.
@Vukasin0 this solution will bundle all translations into your app. This will be problematic for larger applications...
This file loader created a lot of problems for me, from AOT compilation errors to lint errors to big translation bundles.
For Angular Universal I successfully used the prerender from https://github.com/angular/universal-starter with a default language.
@vukasin-nikodijevic your simple solution worked for me thank you.
Thanks @vukasin-nikodijevic, your solution worked perfectly!
Also wanted to add my 2 cents:
Since the different language files are actually objects, I added some more attributes for example "direction":"rtl"
and "textside": "text-right"
(for Bootstrap) to the Hebrew string file, and so I could use the language object throughout the application to control all the behavior related to the selected language.
Also:
Each language file has a code field e.g.: "code": "en"
and I changed the browser's document title like this:
In app.component.ts:
constructor(
public translate: TranslateService,
private titleService:Title
) {
translate.addLangs([en.code, he.code]);
translate.setDefaultLang(en.code);
const browserLang = translate.getBrowserLang();
translate.use(browserLang.match(/en.code|he.code/) ? browserLang : en.code);
this.translate.get("HOME.TITLE").subscribe(title => {
this.titleService.setTitle(title);
});
}
Keep it simple - I'm using
@angular/cli
file: src/shared/lang-switcher/custom-translate-loader.ts
import { en } from "assets/i18n/en"; import { srb } from "assets/i18n/srb"; import { TranslateLoader } from '@ngx-translate/core'; import { Observable } from 'rxjs/Observable'; export class CustomTranslateLoader implements TranslateLoader { public getTranslation(lang: string): Observable<any> { return Observable.create(observer => { if (lang === 'srb') { observer.next(srb); } else { observer.next(en); } observer.complete(); }); } }
file: src/app/app.module.ts
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: CustomTranslateLoader } }),
Translation files
file: src/assets/i18n/en.ts
export const en = { menu: 'Menu', search: 'Search', };
file: src/assets/i18n/srb.ts
export const srb = { menu: 'Meni', search: 'Pretraži', };
Hope this will help someone ;-)
Amazing & Simple
Thnx
Keep it simple - I'm using
@angular/cli
file: src/shared/lang-switcher/custom-translate-loader.ts
import { en } from "assets/i18n/en"; import { srb } from "assets/i18n/srb"; import { TranslateLoader } from '@ngx-translate/core'; import { Observable } from 'rxjs/Observable'; export class CustomTranslateLoader implements TranslateLoader { public getTranslation(lang: string): Observable<any> { return Observable.create(observer => { if (lang === 'srb') { observer.next(srb); } else { observer.next(en); } observer.complete(); }); } }
file: src/app/app.module.ts
TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: CustomTranslateLoader } }),
Translation files
file: src/assets/i18n/en.ts
export const en = { menu: 'Menu', search: 'Search', };
file: src/assets/i18n/srb.ts
export const srb = { menu: 'Meni', search: 'Pretraži', };
Hope this will help someone ;-)
Worked well! 👍
custom-translate-loader.ts
for latest rxjs:
import { of } from 'rxjs';
import { en } from '../../../assets/i18n/en';
import { ar } from '../../../assets/i18n/ar';
import { TranslateLoader } from '@ngx-translate/core';
export class CustomTranslateLoader implements TranslateLoader {
public getTranslation(lang: string) {
if (lang === 'ar') {
return of(ar);
}
return of(en);
}
}
To import CJS modules in TypeScript, use
import fs = require('fs');
. That's the recommended way.