基本的には、ドキュメント通りでOK (日本語版がちと古くなっていたので、英語版参照)

https://nuxtjs.org/guide/plugins

vue-i18n インストール

yarn install vue-i18n

plugins を作る VueI18n を読み込む。ここでやらないと、 asyncData / fetch で使うことができない。

plugins/i18n.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

export default ({ app }) => {
  app.i18n = new VueI18n({
    // とりあえず locale は 日本語に
    locale: 'ja'
  })
}

nuxt.config の設定を変更する

nuxt.config.js
module.exports = {
  build: {
    vendor: ['vue-i18n']
  },
  plugins: ['~/plugins/i18n.js']
}

<i18n> を vue ファイルで書けるようにする

vue-i18n のドキュメントを読むと、vueファイル中に ブロックを記述し、この中に翻訳情報を記すことができるらしい。

ドキュメント

しかし、これをやるには vue ファイルのビルド方法を変えてやる必要がある。ついでに、翻訳データはYAMLで記述したい。

必要なローダーを用意

yarn add -D yaml-loader @kazupon/vue-i18n-loader

vue-loader の設定を上書きする

nuxt.config.js
module.exports = {
  build: {
    extend (config) {
      const vueLoader = config.module.rules.find((r) => {
        return r.loader === 'vue-loader'
      })
      vueLoader.options.preLoaders = vueLoader.options.preLoaders || {}
      vueLoader.options.preLoaders.i18n = 'yaml-loader'
      vueLoader.options.loaders.i18n = '@kazupon/vue-i18n-loader'
    }
  }
}

これで、*.vue ファイルに <i18n> ブロックを記述することができる。
ページ単位で、翻訳データを管理することが出来るのでよい。

<i18n>
ja:
  "Sign in": "ログイン"
</i18n>

<template>
  <div>
    {{ $t('Sign in') }}
  </div>
</template>

また、将来的に翻訳する人と開発する人を分けたりする構想がある場合は、以下のように別ファイルに逃した方がよいかもしれない。

<i18n src="~i18n/login.en.yml"></i18n>
<i18n src="~i18n/login.ja.yml"></i18n>

<template>
  <div>
    {{ $t('Sign in') }}
  </div>
</template>