Nuxt.jsとVue I18nで多言語サイトをつくろう

UI開発者 加藤

Nuxt.jsはVue.jsアプリケーションを構築するためのフレームワークで、シングルページアプリケーションとして構築するか、サーバサイドレンダリングを利用するか、静的サイトとしてファイルを生成するかを設定することができます。静的ファイルを生成する場合、ページごとにvueファイルを用意し、ビルドしてHTMLファイルを生成するのが基本ですが、ルーティング機能をうまく使うことで1つのvueファイルから複数のHTMLを作成することもできます。

Vue I18nはVue.js用に最適化されて作られた国際化対応用のライブラリです。今回はこの2つのライブラリを使い、多言語サイトの静的サイトジェネレータとしてNuxt.jsの開発環境を整えてみます。

前提

今回作成するサイトは下記のようにホスティングすることを想定して作ります。

  • https://example.co.jp/ja/(日本語)
  • https://example.co.jp/en/(英語)

開発環境のフォルダ構成は下記の通りです。

root/
 ├ locales
 │   ├ ja.json
 │   └ en.json
 ├ pages
 │   └ _lang
 │       └ index.vue
 ├ plugins
 │   └ i18n.js
 └ nuxt.config.js

localesに含まれる各言語のJSONファイルには、ページ内で使う文字列データを入れておきます。

// ja.json
{
    "title": "タイトル"
}
// en.json
{
    "title": "title"
}

Vue I18nの準備

pluginsフォルダに含まれるi18n.jsは前述のJSONファイルを読み込み、Vueアプリケーション上でvue-i18nライブラリを使用する準備をします。

import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

export default ({ app }) => {
    app.i18n = new VueI18n({
        fallbackLocale: 'ja',
        messages: {
            'ja': require('~/locales/ja.json'),
            'en': require('~/locales/en.json'),
        }
    });
}

これでライブラリの機能を使用する準備が整いました。あとは各vueファイルの<template>にて、文言を出力する箇所を指定していくだけです。たとえば、JSONファイル内のtitleの値を参照する場合、index.vueでは下記のように書くことができます。

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

しかし、このままでは言語の切り替えができません。そこで、Nuxt.jsが標準で提供している動的なルーティングの機能を使用します。

動的ルーティング

動的ルーティングを使うとアクセスしたURLに応じて処理を分けることができます。ここでは、「/ja」にアクセスした場合は日本語、「/en」にアクセスした場合は英語を表示するようにしたいので、index.vueのscriptに下記のような処理を追加します。

<script>
    export default {
        asyncData(context) {
            return {
                lang: context.params.lang,
            };
        },
        created() {
            // 言語を変更する
            this.$i18n.locale = this.lang;
        }
    };
</script>

たとえば「https://example.co.jp/ja/」にアクセスすると、asyncDataメソッドの引数contextにはパラメータとして「'ja'」が渡されます。その後createdメソッドでページの言語を切り替える処理を行っています。以上でアクセスしたURLに応じて、表示する言語を切り替える仕組みが完成しました。最後は言語ごとのHTMLファイルを生成します。

静的ファイルの生成

静的ファイルを生成するには、nuxt.config.jsgenerateフィールドに生成したいディレクトリを指定します。localesフォルダに含まれるJSONファイルごとのディレクトリを生成するようにルートを設定してみました。

const requireContext = require('require-context');

module.exports = {
    generate: {
        dir: 'public/',
        routes: context => {
            const files = requireContext('../../locales', false, /\.json$/);
            const routes = [];

            files.keys().forEach((key) => {
                routes.push(key.slice(0, -5));
            });

            context(null, routes);
        }
    },
    plugins: ['~/plugins/i18n.js'],
};

設定が完了したら、generateコマンドを実行すれば、指定したディレクトリが生成されます。

静的ファイルはSPAに比べると余計な処理が減りパフォーマンスが向上することも多いため、特に制約がない限りはできるだけ静的ファイルとしてホスティングすることをオススメします。今回はNuxt.jsを使用した多言語静的サイトを構築する仕組みをご紹介しましたが、グローバルWebサイトを構築するには言語、パフォーマンスの他にもさまざま考慮すべき項目があります。グローバル展開への足がかりになれば幸いです。