nuxt-i18nで、同じ言語・パスに対して違う単語を割り当てる

2021/04/04に公開

nuxt-i18nを使って、同じ言語・パスに対して違う単語を割り当てる方法を記載します。

motivation

なぜそんな事をする必要があるのか?という不思議があると思います。これはOEM提供等によって、環境によってある特定の単語を読み替える必要がある、というような場合に利用するためのものです。

概要

  • pluginsで$tの代替となる関数を定義する(ここでは$gt
    • $gtの中では、設定に応じてパスの接尾辞を付加して$tを呼び出す
  • テンプレートでは$tのかわりに$gtを呼び出す
  • i18nタグ等では、接尾辞にあわせてデータを保存する

plugins

以下の内容のファイルを作成します。ここではtsですがjsでもOKかと思います。

gettext.ts
import VueI18n from 'vue-i18n'
import Vue from 'vue'

const env = localStorage.getItem('i18nType') || ''

Vue.use({
  install(Vue) {
    Vue.prototype.$gt = function(key: VueI18n.Path, values?: VueI18n.Values) {
      return this.$t(key + env, values)
    }
  }
})

declare module 'vue/types/vue' {
  interface Vue {
    $gt: typeof Vue.prototype.$gt
  }
}

ここでは、localStorageを直接使って適当にデータを取得しています。アプリケーションの仕組みに応じて、この部分を適宜書き換えるとよいと思います。
また、nuxt.config.jsに追記します。

nuxt.config.js
export default {
  ...
  plugins: ['plugins/gettext.ts'],
  ...
}

実際の呼び出し方法

some-page.vue
<template>
  <div>{{ $gt('Hello') }}</div>
</template>
<script>
// 省略
</script>
<i18n>
  {
    "ja": {
      "Hello": "やあ",
      "Hello_v2": "こんにちは!!!"
    },
    "en": {
      "Hello": "Hi",
      "Hello_v2": "Hello!!!"
    }
  }
</i18n>

これで、localStorageのi18nTypeに空文字列をセットすればHelloの内容が、_v2をセットすればHello_v2の内容が、それぞれ出力されるようになります。

Discussion