基本的には公式サイトのInternationalizationの説明の通り。
ただコンパイル方法がJITとAOTによって違ったり、どの情報を元に言語を切り替えるかが開発者に任せられる前提だったので、自分のやりたい方法で多言語化できるまでに少しハマったので、国際化する方法をメモしておきます。
コンパイル方法による違い
AOTとJITがあります。
AOT
AOTは事前に言語リソースも含めてビルドする形になるので、動的に変更することができません。
よってURL自体を分けてしまう場合や、Webサーバーの機能で表示するページを振り分ける場合などに使用できます。
Angular自体の速度はAOTの方が早いようです。
JIT
JITはページ表示後にAngularのコンパイル的なことをごにょごにょするみたいです。
パフォーマンスはAOTに劣るようですが、動的な言語リソースの選択が可能です。
私は今回JITコンパイルを採用しました。
S3にコンテンツを配置するのでブラウザの言語によって、返すコンテンツを変更する事が難しい(よく調べてない)点と、どの言語も同じURLでアクセスできるようにしたかったからです。
出し分け方法
Internationalizationによるとmain.ts
は以下のようになります。
import { enableProdMode, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
// use the require method provided by webpack
declare const require;
// we use the webpack raw-loader to return the content as a string
const translations = require(`raw-loader!./locale/messages.fr.xlf`);
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'}
]
});
このプログラムだと固定の言語、今回はfr
なのでフランス語にしか翻訳されたページが表示されません。
今回やりたかったことは、ブラウザの言語設定(chromeの設定から変更できる言語も考慮)に応じて切り替えることだったので、次のようにmain.ts
を変更しました。
import {enableProdMode, TRANSLATIONS_FORMAT, TRANSLATIONS} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import 'hammerjs';
import {AppModule} from './app/app.module';
import {environment} from './environments/environment';
if (environment.production) {
enableProdMode();
}
declare const require;
// 日本語の場合のみ日本語に翻訳する
const translationProviders = (() => {
// ブラウザの言語を取得
const browserLanguage: string = (() => {
console.log(navigator.languages);
if (navigator.languages.length > 0) {
return navigator.languages[0];
}
if (navigator.language) {
return navigator.language
}
return "en";
})();
console.log(browserLanguage);
// 日本語だったら翻訳設定
if (browserLanguage.match(/^ja$|^ja-/)) {
const translations = require('raw-loader!./locale/messages.ja.xlf');
return [
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},
]
}
})();
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [].concat(translationProviders) // 翻訳が必要な場合のみ、翻訳に必要なプロバイダーを追加する
})
.catch(err => console.log(err));
これでブラウザの言語に応じて、英語と日本語の出し分けができるようになりました。