【Nuxt3】簡単！i18nで多言語化対応&パフォーマンス最適化！

閲覧頂き、ありがとうございます🙇

この記事は、Nuxt3の多言語対応を行うために
`@nuxtjs/i18n`の導入とパフォーマンスの最適化の手順を紹介します！

# 前提

| name | version |
| - | - |
| Nuxt.js(Vue.js) | v3.x |

# 経緯

Nuxt3で多言語化対応をする方法を調べていき`@nuxtjs/i18n`に辿り着きました。
導入方法とともに、各言語の定義ファイルを効率よく読み込む方法を調査・実装しました。

# ざっくり3行まとめ💨

* `@nuxtjs/i18n`をインストールし、各言語の定義ファイルを用意することで`多言語化対応が可能`🌏
* デフォルトのままでは現在表示中の言語以外の定義ファイルも読み込んでしまい`重くなる`🏋️
* 遅延読み込みのオプションがあり、パフォーマンスが最適化できる💯

# @nuxtjs/i18n の導入

## インストール📝

```bash
$ npm i @nuxtjs/i18n
```

## nuxt.config.tsの設定📝

```nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/i18n',
  ],
  i18n: {
    strategy: 'prefix_except_default', // デフォルト言語はプレフィックス無し
    defaultLocale: 'ja', // デフォルト言語を日本語
    // 各言語の設定
    locales: [
      { code: 'ja', language: 'ja-JP', name: 'Japanese', file: 'ja.ts' },
      { code: 'en', language: 'en-US', name: 'English', file: 'en.ts' },
      { code: 'fr', language: 'fr-FR', name: 'French', file: 'fr.ts' },
    ],
    // 言語ファイルが格納されているファイル(外部ファイルかする場合)
    langDir: 'locales',
  },
})
```

## 翻訳ファイルの作成📝

今回は、「日本語」「英語」「フランス語」で、
`「こんにちは」`を各言語で表示するための設定をします。

```locales/ja.ts
export default defineI18nLocale(async () => ({
  // nameはテキストを表示する際に引数を渡すことができる部分
  hello: 'こんにちは、{name}！',
  language: '言語',
}))
```

```locales/en.ts
export default defineI18nLocale(async () => ({
  hello: 'Hello, {name}!',
  language: 'Language',
}))
```

```locales/fr.ts
export default defineI18nLocale(async () => ({
  hello: 'Bonjour, {name}!',
  language: 'Langue',
}))
```

## Vueファイルに実装📝

今回は`<NuxtPage />`を使用し、トップページに実装します！

```pages/index.vue
<script setup lang="ts">
// setLocaleは現在の表示言語を切り替えるための関数
const { setLocale } = useI18n()
</script>
<template>
  <div>
    <!-- $tは翻訳ファイルを参照するために使用する関数 -->
    <h1>{{ $t('hello', {name: 'vue-i18n'}) }}</h1>
    <p>{{ $t('language') }}</p>
    <button @click="setLocale('ja')">ja</button>
    <button @click="setLocale('en')">en</button>
    <button @click="setLocale('fr')">fr</button>
  </div>
</template>

```

## 画面の確認👀

ボタンの切り替えで各言語の切り替えできていることを確認できました！

![i18n.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130422/4dec7d78-84e6-6ccf-35a8-b6c4dac85f37.gif)

## ここで問題が発生🚨

初回の読み込み時点で、
他言語(英語とフランス語)の翻訳ファイルも読み込んでしまい、
パフォーマンスの低下につながらないか気になった🤔

![スクリーンショット 2024-10-06 23.59.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130422/d2ae5ccd-50dc-e10f-3e91-2aa45db2770b.png)

## 翻訳ファイルの遅延読み込みをする⚒️

`@nuxtjs/i18n`には`遅延読み込み`(LazyLoad)機能があり、
こちらで懸念点の解消できたので紹介！

対応方法としては、
`nuxt.config.ts`に1つだけオプションを追加するだけ💡

```nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/i18n',
  ],
  i18n: {
    strategy: 'prefix_except_default',
    defaultLocale: 'ja',
    locales: [
      { code: 'ja', language: 'ja-JP', name: 'Japanese', file: 'ja.ts' },
      { code: 'en', language: 'en-US', name: 'English', file: 'en.ts' },
      { code: 'fr', language: 'fr-FR', name: 'French', file: 'fr.ts' },
    ],
    lazy: true, // ←←←　ここを追加📝
    langDir: 'locales',
  },
})
```

再度確認してみると・・・

![i18nex.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130422/9d8c8c4f-fcbc-ec89-a0bb-f08d78d2fede.gif)

初回読み込みでは`ja.ts(デフォルト言語)のみ読み込み`となりました🎉
また他言語は選択時に翻訳ファイルが読み込まれるようになりました🎉

# 最後に🍵

今回はNuxt3での多言語化について学びました！
細かな設定はまだまだあると思うのですが、最低限の実装完了ができました！

大規模サイトとなって場合、
どのように翻訳ファイルを作るのかがあまり想像ついてませんが、
自動翻訳より精度の高いテキストを出すことができることは良いと思いました！

実務での利用は僕自身まだないですが、
グローバルな対応はサービスの価値を世界に発信できるので、
利用してみたいです！

# 宣伝・・・

以下の記事も書いているので見てくれたら喜びます🐸

* [【Nuxt3】簡単！@nuxt/eslintを使ったESLintとフォーマッタの設定 ※2024年版](https://qiita.com/yuki_s_14/items/96620ccfb1dd897ce9f3)
* [【Nuxt3】5分で完了！Vitest と Testing Libraryを用いた単体テスト実行環境を作る！](https://qiita.com/yuki_s_14/items/be8416bd392065fda30a)
* [【Nuxt3】definePropsの分割代入の変数をリアクティブにしたい！](https://qiita.com/yuki_s_14/items/cd314d30b179e9fb8363)
* [【Nuxt3】NuxtIslandとサーバーコンポーネントで軽量化！](https://qiita.com/yuki_s_14/items/db19efb6ded93d23ee5d)



# 参考記事
* [公式 - @nuxtjs/i18n](https://i18n.nuxtjs.org/)
* [今回使用したNuxt環境(Github)](https://github.com/yuki-s-14/nuxt3-simplest-starter/tree/feature/add-i18n)