I used inertiajs for the combination of Laravel and Vue. But the basic procedures remain the same.
Setup i18n-vue
The configuration and usage assumes the use of the Option API of Vue.
For the composition API, the setup looks different. And this.$i18n.locale cannot be accessed directly.
See then https://vue-i18n.intlify.dev/guide/advanced/composition.html#basic-usage
app.js
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
const i18n = createI18n({
locale: "de",
// locale: props.initialPage.props.locale, // user locale by props
fallbackLocale: "en", // set fallback locale
messages: loadLocaleMessages(),
});
return createApp({ render: () => h(app, props) })
.use(plugin)
.use(i18n)
.mixin({ methods: { route } })
.mount(el);
},
});
The Laravel locale is set via a LanguageMiddleware. From the session or if it is missing from the config.
class LanguageMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if(session()->has('locale')){
app()->setLocale(session('locale'));
} else {
app()->setLocale(config('app.locale'));
}
return $next($request);
}
}
The LanguageMiddleware must be declared in the kernel:
...
protected $middlewareGroups = [
'web' => [
...
\App\Http\Middleware\LanguageMiddleware::class,
],
];
...
In the Web Routes the route is defined to change the locale in the session.
web.php
Route::put('/laravel-language/{key}', function ($key) {
session()->put('locale', $key);
return redirect()->back();
});
The locale switcher is displayed in the frontend:
Authenticated.vue
<div v-if="$i18n.locale == 'en'">
<a @click.prevent="switchLanguage('de')" href="#"> Deutsch </a>
</div>
<div v-if="$i18n.locale == 'de'">
<a @click.prevent="switchLanguage('en')" href="#"> English </a>
</div>
and the method switchLanguage is called. The method changes both the locale of i18n-vue and calls the route to change the Laravel locale.
<script>
export default {
methods: {
switchLanguage(key) {
this.$i18n.locale = key;
this.$inertia.put('/laravel-language/' + key);
},
},
}
</script>