30
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NextJSで各国語対応してみた

Last updated at Posted at 2019-12-09

以前、NextJSといったJavaScriptフレームワークを使ってWEBアプリを作っていたときの話。
メインは日本人だが、外国人も使えるアプリにする必要があった。

  1. Google翻訳APIを使う
  2. Google以外の自動翻訳してくれるサービスを利用する
  3. 各国に対応したページを量産する
  4. 指定した文言であって欲しい

色々と実装方法はあるが、どれもマッチしない。
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のパラメータが変わり
指定の言語に切り替わることが確認できると思います。

ja.png
en.png
zh.png

Translate.gif

長文やページデザインも変更するような場合は、今回紹介した内容では対応できませんが、
簡単な翻訳機能であれば、外部の翻訳サービスを一切使わずに実装できちゃいました。

本記事で使ったソースは、GitHubで公開しています。
https://github.com/wild-lycaon/poc-nextjs-translate

では、またどこかで。

30
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?