以前、NextJSといったJavaScriptフレームワークを使ってWEBアプリを作っていたときの話。
メインは日本人だが、外国人も使えるアプリにする必要があった。
- Google翻訳APIを使う
- Google以外の自動翻訳してくれるサービスを利用する
- 各国に対応したページを量産する
- 指定した文言であって欲しい
色々と実装方法はあるが、どれもマッチしない。
3は論外、4が重要!
適当な直訳ではダメ、言い回しも業界に合わせる必要があった。
さて、どうするか…
無いものは作っちゃえ!(← 好きです。この言葉)
ということで、用意するのはJSONファイルと簡単なスクリプト。
今回は、NextJS を使った実装方法を紹介します。
Next.JS ついては → https://nextjs.org/
環境の準備ですが、事前にNode.jsが動作する環境が必要です。
次にNextJS環境。
こちら最新バージョンではデフォルトでTypeScriptが使えて So Cool!
公式ドキュメントに従い、簡単に環境作っちゃいましょう。
> npx create-next-app
TypeScriptを有効にするには、ルートにtsconfig.json
が必要だったり、別途モジュール
が必要だったり。
ちょっとだけゴニョゴニョして環境出来上がり。
> npm run dev
とかすると http://localhost:3000 で確認できます。
ウォッチ状態なので、このままコーディングすると自動的に反映され、リアルタイムで動作を確認できます。
では早速、表示するページを用意しましょう。
pagesディレクトリに既に index.js を書き換えちゃいます。
export default () => (
<div>
<Head>
<title>Translate</title>
</Head>
<p>ここの</p>
<p>文字列が</p>
<p>翻訳されます</p>
<p>ただし、辞書に無いものはそのまま表示されます</p>
</div>
)
言語を変えるためのボタンを用意します。
今回は「日本語」「英語」「中国語」への変換を行うこととします。
同時に、クリックした際のイベントハンドラも用意しましょう。
ボタンをクリックすると、LanguageUtil.setLanguage(...) が呼ばれる仕組みです。
<form>
<button value='ja' onClick={changeLanguage}>日本語</button>
<button value='en' onClick={changeLanguage}>英語</button>
<button value='zh' onClick={changeLanguage}>中国語(簡体)</button>
</form>
const changeLanguage = event => {
event.preventDefault()
const language = event.currentTarget.value
setLanguage(language)
}
その LanguageUtil.setLanguage(...) の実体。
URLのクエリ―パラメータに、langとして、押されたボタンのvalue値をセットしています。
export const setLanguage = (language: string): void => {
const { pathname, search } = window.location
const query = parse(search.replace('?', ''))
query['lang'] = language
Router.replace({ pathname, query }).then()
}
次に、翻訳の中心的な存在となるJSONファイルを用意しましょう。
翻訳したい文字列をキーにして、各国コード用の文言を用意します。
↓適当な翻訳です。
{
"ここの": {
"en": "This",
"zh": "这个"
},
"文字列が": {
"en": "string is",
"zh": "字符串是"
},
"翻訳されます": {
"en": "translated",
"zh": "已翻译"
}
}
キーの値(文言)と、国コードを渡すと、その国コードに対応した文言が返るメソッドを用意します。
その際、国コードはクエリ―ストリングから取得するようにします。
NextJSはサーバ上でも動作するため、Windowオブジェクトが有るか事前にチェックする必要があったりします。
export const getLanguage = (): string => {
if (!hasWindow()) return 'ja'
const { search } = window.location
const query = parse(search.replace('?', ''))
return _.get(query, 'lang', 'ja') as string
}
export const translate = (word: string): string => {
const lang = getLanguage()
return _.get(_translates, `${word}.${lang}`, word)
}
最後にページを修正します。
翻訳したい文字列を translate(...) で囲うだけです。
export default () => (
<div>
<Head>
<title>Translate</title>
</Head>
<form>
<button value='ja' onClick={changeLanguage}>日本語</button>
<button value='en' onClick={changeLanguage}>英語</button>
<button value='zh' onClick={changeLanguage}>中国語(簡体)</button>
</form>
<p>{translate('ここの')}</p>
<p>{translate('文字列が')}</p>
<p>{translate('翻訳されます')}</p>
<p>{translate('ただし、辞書に無いものはそのまま表示されます')}</p>
</div>
)
それぞれの言語ボタンをクリックすると、URLのパラメータが変わり
指定の言語に切り替わることが確認できると思います。
長文やページデザインも変更するような場合は、今回紹介した内容では対応できませんが、
簡単な翻訳機能であれば、外部の翻訳サービスを一切使わずに実装できちゃいました。
本記事で使ったソースは、GitHubで公開しています。
https://github.com/wild-lycaon/poc-nextjs-translate
では、またどこかで。