LoginSignup
27

More than 5 years have passed since last update.

Nuxt.jsでいい感じにi18nを使う

Last updated at Posted at 2017-09-02

Nuxt 国際化(i18n)
https://ja.nuxtjs.org/examples/i18n/

上記ページのサンプルは、 /en やら /fr みたいなパスベースで切り替える感じだけど、あんま好きくないのでブラウザの設定ベースで言語を切り替えるようにする。

パスベースじゃないのでサンプルにある vue-routermiddleware/i18n.js は不要。

vue-i18n はイケてるけど英語の設定で最初の1文字目を大文字にしたい〜みたいなところは特に標準では対応してないので適当にfunctionを追加。

というわけで僕が考えた最強のNuxtの plugins/vue-i18n.js

plugins/vue-i18n.js
import _ from 'lodash';
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import changeCase from 'change-case';

Vue.use(VueI18n);

// 各種大文字/小文字切り替え用のfunctionを用意する
Vue.mixin({
  methods: {
    // camelCaseにする
    $tcc(path) {
      return changeCase.camelCase(this.$t(path));
    },
    // 1文字目をupperCaseにする
    $tucf(path) {
      return changeCase.upperCaseFirst(this.$t(path));
    },
    // 1文字目をlowerCaseにする
    $tlcf(path) {
      return changeCase.lowerCaseFirst(this.$t(path));
    },
    // 全部upperCaseにする
    $tuc(path) {
      return changeCase.upperCase(this.$t(path));
    },
    // 全部lowerCaseにする
    $tlc(path) {
      return changeCase.lowerCase(this.$t(path));
    }
  }
});

export default ({ app, req, isClient }) => {
  // 標準はja
  let locale = 'ja';
  if (isClient) {
    // browserから取る場合はnavigator経由で取得
    const navigator = _.get(window, 'navigator', {});
    locale = (_.head(navigator.languages) || navigator.language || navigator.browserLanguage || navigator.userLanguage).substr(0, 2);
  } else if (req) {
    // ssrの場合はrequestから取得
    locale = req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substr(0, 2);
  }
  app.i18n = new VueI18n({
    locale: locale || 'ja',
    fallbackLocale: 'ja',
    messages: {
      'en': require('~/locales/en.json'),
      'ja': require('~/locales/ja.json'),
    },
  });
}

これで以下のように使う場所に応じて大文字・小文字を切り替えられる。

locales/en.json
{"app": {"brand": "my application"}}
locales/ja.json
{"app": {"brand": "僕のアプリ"}}
components/Header.vue(テンプレート内に書く場合)
<template>
  <div class="navbar-header">
    <nuxt-link to="/" class="navbar-brand">{{$tuc('app.brand')}}</nuxt-link>
  </div>
</template>
components/Header.vue(jsから渡す場合)
<template>
  <div class="navbar-header">
    <nuxt-link to="/" class="navbar-brand">{{brand}}</nuxt-link>
  </div>
</template>
<script>
export default {
  data() {
    return {
      brand: this.$tuc('app.brand'),
    };
  },
};
</script>

たぶんこんな感じのやつで、英語なら「MY APPLICATION」ってなるし日本語「僕のアプリ」って表示されるはず。

参考

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
27