猫でもわかるWeb開発・プログラミング

本業エンジニアリングマネージャー。副業Webエンジニア。Web開発のヒントや、副業、日常生活のことを書きます。

Scala Play + Vue.js の多言語対応

https://cdn.lgtmoon.dev/images/80129

LGTM画像生成サイト LGTMoon で多言語対応してみましたので、どのような対応を行ったかをまとめます。

LGTMoon - 最もシンプルなLGTM画像ジェネレーター

Vue.js

フロントエンドは Vue.js で組まれています。

多言語化には vue-i18n を使います。

yarn add vue-i18n

設定

import Vue from 'vue'
import App from '@/App.vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n);

const messages = {
  ja: {
    menu: {
      recent: "最近の画像",
      random: "ランダム",
      favorite: "お気に入り",
      help: "使い方"
    }
  },
  en: {
    menu: {
      recent: "Recent",
      random: "Random",
      favorite: "Stars",
      help: "Help"
    }
  }
}

const i18n = new VueI18n({
  // navigator.language でブラウザの設定言語が習得できる
  // en-US とか ja-JP が返ってくるのだが、
  // 今回は en と ja の部分だけ使いたいので split して 0 を取る
  locale: navigator.language.split('-')[0],
  // 対応する言語が無い場合は英語にする
  fallbackLocale: 'en',
  messages,
})

new Vue({
  render: h => h(App),
  i18n
}).$mount('#app');

テンプレート部分

<div v-on:click="recent()">
  {{ $t('menu.recent') }}
</div>
<div v-on:click="random()">
  {{ $t('menu.random') }}
</div>
...

これで、ブラウザの設定言語を見て自動的に翻訳されます。

f:id:yoshiki_utakata:20200405112922p:plain

注意点

Google bot が SPA に対応した場合、 fallbackLocale が使われる可能性が高いかなと思っており*1、fallbackLocakeがenになっていると、日本語での検索順位が落ちる可能性があります。

後に述べるScala側の対応のように、言語ごとにページを分ける方法のほうが無難な気もします。

Scala Play

Vue.js 側は対応できたのですが、Vue では title タグやメタタグの翻訳ができません。

この問題については、日本語版と英語版のページを分けるのが簡単という結論に達しました。

Scala Play を使っているので、route の設定を追加します。

GET     /en    @controllers.Assets.at(path="/public", file="en.html")
GET     /      @controllers.Assets.at(path="/public", file="index.html")

SEO等のための対応

html lang="en"

それぞれのページに、 <html lang="ja"> または <html lang="en"> を入れます。Google の bot はこの値を見ていないような気がしますが、念の為入れておきます。

metaタグを翻訳

英語版の方は meta タグの中身を英語にしておきます。

link alternate

各ページに、日本語と英語のページのURLを明記します。

<link rel="alternate" href="https://lgtmoon.herokuapp.com/en" hreflang="en" />
<link rel="alternate" href="https://lgtmoon.herokuapp.com/" hreflang="ja" />

content-language

以下のようなタグを、英語と日本語のページ両方に入れておきます。 bing *2 がこれを見ているようです。

<meta http-equiv="content-language" content="en">

海外では bing もそこそこ使われているようです。国際化を考えるといろいろな検索サイトに対応しなければなりませんし(Baidu*3とか)、こういった対応は全部入れておくのが良いと思いました。

まとめ

これで十分なのかわかりませんが、一旦これで、しばらく様子を見ようと思います。

vueがブラウザのLocaleを見ているのだけは改善したいです。

その他、サーチコンソールなどの結果や、さらなる改善点などあったらまた書きたいと思います。

参考

*1:Google の Bot は Accept Language をつけないでアクセスしてくるようなので

*2:マイクロソフトの検索サービスです

*3:中国の検索サービス