Table of Contents
はじめに
LaravelとVueのプロジェクトで多言語対応する場合に翻訳ファイルを共通で使いたい場合があります(とくにattributesなど重複することがあるので)。
Laravel標準機能として JSONファイルを翻訳ファイルとして扱うことができ、それをVue I18nで読み込むなど共通化できる方法はありますが、ファイル分割やネストした書き方ができないなど、若干不便な部分があります。
そこで Laravel Vue i18n というライブラリを使うことで通常のPHPの翻訳ファイルのまま、Vueでもその翻訳ファイルを使えるように。
基本的にドキュメント通りのやり方で問題ありませんでした。
環境
- Laravel 10
- Breeze (Vue3 + Vite + Inertia)
- TypeScript
Laravelプロジェクトの作成はBreezeのtypescriptオプションを使って作成しました。
langディレクトリ作成
まずはlangディレクトリを用意します。
lang/en以下にauth.phpやvalidation.phpが作られると思います。
$ php artisan lang:publish
Laravel Vue i18nの導入
インストール
次にLaravel Vue i18nをインストールします。
$ npm install -D laravel-vue-i18n
Vite設定
まずはvite.config.jsにプラグインを追加します。
これによりビルド時や開発サーバー起動時にauth.phpやvalidation.phpから自動でJSONファイルに変換された翻訳ファイルが生成されます。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import i18n from 'laravel-vue-i18n/vite'; // <- 追加
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.ts',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
i18n(), // <- 追加
],
});
Vue設定
次にresources/js/app.tsを編集します。
i18nVueをimportしてきてVueに追加してあげます。resolveの部分についてはドキュメント通りlang以下の*.jsonを読み込んであげる形になります。
import './bootstrap';
import '../css/app.css';
import { createApp, h, DefineComponent } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
import { i18nVue } from 'laravel-vue-i18n' // <- 追加
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob<DefineComponent>('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, Ziggy)
// ----- ここから追加 -----
.use(i18nVue, {
resolve: async (lang: string) => {
const langs = import.meta.glob('../../lang/*.json');
return await langs[`../../lang/${lang}.json`]();
}
})
// ----- ここまで追加 -----
.mount(el);
},
progress: {
color: '#4B5563',
},
});
lang
オプションを指定しない限りは <html lang="en">
タグから自動で探してきて言語設定してくれるようですので、app.blade.phpで正しく指定してあればとくに問題はありません。
動かしてみる
設定が完了したのでViteサーバーを起動してみます。
$ npm run dev
するとlang/en以下にあるphpファイルを基にlang/php_en.jsonというファイルが出力されます。
これをVue側で読み込んで使用している仕組みのようです(php_en.jsonはViteサーバー終了後には削除されます)。
{
"auth.failed": "These credentials do not match our records.",
"auth.password": "The provided password is incorrect.",
"auth.throttle": "Too many login attempts. Please try again in :seconds seconds.",
"pagination.previous": "« Previous",
"pagination.next": "Next »",
"passwords.reset": "Your password has been reset.",
...
}
そしてVueのtemplateタグ内で以下のように書けるようになります。auth.phpで記述したテキストが表示されるようになります。
<template>
<div>
{{ $t('auth.failed') }}
</div>
</template>
これでLaravel側で利用している翻訳ファイルをそのままVueで利用できるようになりました。
おわりに
Laravel Vue i18nを使ってLaravelとVue間で翻訳ファイルを共通化することができました。
設定も簡単でスムーズに動かすことができました。
ただ、共通化することでLaravel側で使わない翻訳テキストもPHPファイルに書いて管理することになるので、運用方法やプロジェクト構成によっては利用を考える必要がありそうです。
Related Posts
Daiki Urata
2023/01/05
sarah
2022/04/20