Laravel Jetstream+Vueの多言語化(i18n)
はじめに
この記事を読むと、Laravel Jetstream+Vue環境をja.json等のファイルによって多言語化(i18n)できるようになります。
多言語化にはvue-i18nを使用します。
Jetstreamではフロントエンドとして、livewireまたはVueを選択できます。
livewireバージョンは既に多言語化対応されています。
しかし、現状、Vueバージョンの方は多言語化対応されていません。
この記事ではフロントエンドとしてvueを選択した場合の多言語化(i18n)について解説します。
(2021年10月12日追記)
Laravel+Jetstream(Vue)+Vite環境化での多言語化(i18n)に関する記事を追加しました。
Vite環境化で多言語化する場合は以下の記事をご覧ください。
バージョン情報
- PHP 8.0.9
- laravel/framework: v8.62.0
- vue@3.2.11
- @inertiajs/inertia@0.10.1
- @inertiajs/inertia-vue3@0.5.2
- @intlify/vue-i18n-loader@3.0.0
多言語化(i18n)
1.ja.jsonファイル作成
以下のコマンドを実行し、ja.jsonファイルを自動生成します。
$ sail composer require laravel-lang/lang:~8.1.3 --dev
$ cp vendor/laravel-lang/lang/json/ja.json resources/lang/
2.多言語化に関するソースコード修正
vue-i18nをインストールします。
NPM
$ sail npm install vue-i18n@next
Yarn
$ sail yarn add vue-i18n@next
ルートテンプレートにlocaleを定義します。
<!-- Scripts -->
@routes
<script>
var __locale = '{{ app()->getLocale() }}'
</script>
<script src="{{ mix('js/app.js') }}" defer></script>
app.jsに多言語化(i18n)を追加します。
legacy: false、globalInjection: trueを指定することでグローバルに、どのvueファイルからでもメッセージ翻訳関数の使用が可能になります。
また、loadLocaleMessages関数により多言語化ファイル(ja.json等)を読み込みます。
詳細はvue-i18nのドキュメントをご確認ください。
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { createI18n } from 'vue-i18n'
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
async function loadLocaleMessages(i18n, locale){
const messages = await import(`../lang/${locale}.json`)
i18n.global.setLocaleMessage(locale, messages.default)
}
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
async setup({ el, app, props, plugin }) {
const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: __locale
})
await loadLocaleMessages(i18n, __locale)
return createApp({ render: () => h(app, props) })
.use(plugin)
.use(i18n)
.mixin({ methods: { route } })
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });
以上で、多言語化に関するソースコード修正は完了です。
vueファイルの修正
日本語化する箇所について以下のように修正します。
主な修正箇所は以下です。
- 文字列、タイトル、ボタン名、リンク名
- ラベル
- プレースホルダ
(livewireバージョンは既に同じような修正が入っています。)
フォーマットについてはvue-i18nのドキュメントをご確認ください。
<template>
<Head :title="$t('Log in')" />
<jet-authentication-card>
<template #logo>
<jet-authentication-card-logo />
</template>
<jet-validation-errors class="mb-4" />
<div v-if="status" class="mb-4 font-medium text-sm text-green-600">
{{ status }}
</div>
<form @submit.prevent="submit">
<div>
<jet-label for="email" :value="$t('Email')" />
<jet-input id="email" type="email" class="mt-1 block w-full" v-model="form.email" required autofocus />
</div>
<div class="mt-4">
<jet-label for="password" :value="$t('Password')" />
<jet-input id="password" type="password" class="mt-1 block w-full" v-model="form.password" required autocomplete="current-password" />
</div>
<div class="block mt-4">
<label class="flex items-center">
<jet-checkbox name="remember" v-model:checked="form.remember" />
<span class="ml-2 text-sm text-gray-600">{{ $t('Remember me') }}</span>
</label>
</div>
<div class="flex items-center justify-end mt-4">
<Link v-if="canResetPassword" :href="route('password.request')" class="underline text-sm text-gray-600 hover:text-gray-900">
{{ $t('Forgot your password?') }}
</Link>
<jet-button class="ml-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
{{ $t('Log in') }}
</jet-button>
</div>
</form>
</jet-authentication-card>
</template>
その他のvueファイルについても同様の修正が必要です。
注意点
Register.vueの以下の箇所だけは、今回の対応では日本語化できません。
直接修正する必要があります。
その他のvueファイルについては対応可能です。
I agree to the <a target="_blank" :href="route('terms.show')" class="underline text-sm text-gray-600 hover:text-gray-900">Terms of Service</a> and <a target="_blank" :href="route('policy.show')" class="underline text-sm text-gray-600 hover:text-gray-900">Privacy Policy</a>
まとめ
全てのvueファイルを日本語化するのは骨が折れますね(汗)
でも、1時間もあれば十分に全箇所修正可能です(笑)
近い将来、Vueの多言語化も正式にサポートされたら嬉しいですね。
Discussion