🚄

Laravel+Jetstream(Vue)+Vite環境での多言語化(i18n)

4 min read

はじめに

以前、Laravel+Jetstream(Vue)の多言語化に関する情報をまとめました。

https://zenn.dev/yamabiko/articles/jetstream-i18n

今回はVite環境下での多言語化について解説します。
この記事を読むと、以下の動画のようにロケールファイルの修正を瞬時に反映できるようになります。

バージョン情報

  • PHP: 8.0.11
  • laravel/framework: v8.63
  • laravel/jetstream: v2.4.2
  • laravel/sail: v1.11.0
  • laravel-lang/lang: 8.1.3
  • vue@3.2.20
  • vite@2.6.5
  • @intlify/vite-plugin-vue-i18n@2.4.0

前提条件

Laravel+Jetstream(Vue)+Vite環境を構築済みであること。

Vite環境構築については以下の記事をご覧ください。

https://zenn.dev/yamabiko/articles/laravel-jetstream-vite

多言語化

以下のコマンドを実行し、ja.jsonファイルを自動生成します。

$ sail composer require laravel-lang/lang:~8.1.3 --dev
$ cp vendor/laravel-lang/lang/json/ja.json resources/lang/

vite-plugin-vue-i18nをインストールします。

$ sail npm i --save-dev @intlify/vite-plugin-vue-i18n

作成したロケールファイル(ja.json)を読み込む設定を追加します。

vite.config.js
import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';
+import vueI18n from '@intlify/vite-plugin-vue-i18n'

export default defineConfig(({ command }) => ({
  base: command === 'serve' ? '/' : '/dist/',
  build: {
    manifest: true,
    outDir: path.resolve(__dirname, 'public/dist'),
    rollupOptions: {
      input: 'resources/js/app.js',
    },
  },

  plugins: [
    vue(),
+    vueI18n({
+      include: path.resolve(__dirname, './resources/lang/**')
+    })
  ],

  server: {
    host: '0.0.0.0'
  },

  resolve: {
    alias: {
      '@': path.resolve(__dirname,'/resources/js'),
    },
  },
}));

ポイントは、パス指定するときにドット(.)が必要である点です。
ドットが無いとロケールファイルが読み込まれません。。

次に、ルートテンプレートを編集します。
app.jsにロケール情報を伝えるために、jsのグローバル変数にロケール情報をセットします。

resources/views/app.blade.php
        <!-- Scripts -->
+        <script>
+            window.__locale = '{{ app()->getLocale() }}'
+        </script>
        @routes
        <!-- Vite -->
        @vite

次に、app.jsに多言語化(i18n)対応を追加します。

resources/js/app.js
import './bootstrap'

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
+import { createI18n } from 'vue-i18n'
+import messages from '@intlify/vite-plugin-vue-i18n/messages'
import '../css/app.css'

const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: async name => {
        if (import.meta.env.DEV) {
            return await import(`./Pages/${name}.vue`)
        } else {
            let pages = import.meta.glob('./Pages/**/*.vue')
            const importPage = pages[`./Pages/${name}.vue`]
            return importPage().then(module)
        }
    },
    setup({ el, app, props, plugin }) {

+        const i18n = createI18n({
+            legacy: false,
+            globalInjection: true,
+            locale: __locale,
+            messages
        })

        return createApp({ render: () => h(app, props) })
            .use(plugin)
+            .use(i18n)
            .mixin({ methods: { route } })
            .mount(el);
    },
});

InertiaProgress.init({ color: '#4B5563' });

legacyオプションにfalse、globalInjectionオプションにtrueを指定することでグローバルに、どのvueファイルからでもメッセージ翻訳関数($tなど)の使用が可能になります。
詳細はvue-i18n公式ドキュメントをご確認ください。

また、vite-plugin-vue-i18nは「@intlify/vite-plugin-vue-i18n/messages」識別子にて、vite(rollup)メカニズムを使用して、すべてのロケールを一度にインポートできます。

多言語化対応については以上になります。

完全なソースコードは以下になります。

https://github.com/YamabikoHatake/vite-jetstream-i18n-app
Vite環境構築直後と多言語化後のソースコードの比較は以下になります。
https://github.com/YamabikoHatake/vite-jetstream-i18n-app/compare/vite...i18n

動作確認

ja.jsonファイルを編集すると、瞬時に反映されます。

まとめ

Jetstreamのlivewireインストール版は既に多言語化対応が実装されています。
しかし、Vue版は未だ多言語化対応されていません。
私も多言語化の実現方法をネットで調査しましたが、多くの人が様々な方法で実装しているようです。
近い将来、公式に多言語化がサポートされるといいですね。

とにかく、Jetstrem+Vite+多言語化で、Jetstreamを拡張するためのより良いスタートラインに立てるのではないかと思います😄

次のステップとして、以下のログ出力の記事がご参考になれば幸いです。

https://zenn.dev/yamabiko/articles/laravel-logging

さらに、Jetstreamでのソーシャルログインにご興味のある方は以下の記事をご覧ください。

https://zenn.dev/yamabiko/articles/jetstream-socialite

Discussion

ログインするとコメントできます