Laravel and Vue.js Translations with i18n Plugin

Translating your Vue.js application might be challenging if you want to use Laravel translation files, but there's an easy way. To connect Laravel translation files for Vue application, we will use laravel-vue-i18n Vue plugin.

We have already set up a new Laravel installation with Laravel Breeze Vue starter kit. Let's get started.


Install laravel-vue-i18n Plugin

To install the laravel-vue-i18n Vue.js plugin, run this NPM command.

npm i laravel-vue-i18n

Then, update the Vite configuration file by adding the Vite plugin from the package.

vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import i18n from 'laravel-vue-i18n/vite';
 
// ...
 
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
i18n()
],

In your main app.js file, include the laravel-vue-i18n plugin.

resources/js/app.js

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 = import.meta.env.VITE_APP_NAME || 'Laravel';
 
// ...
 
return createApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, Ziggy)
.use(i18nVue, {
resolve: async lang => {
const langs = import.meta.glob('../../lang/*.json');
return await langs[`../../lang/${lang}.json`]();
}
})
.mount(el);

The plugin will load your Laravel translations from JSON files in the /lang folder from your project root.

Add Translations

Now, we can start adding our translations. In this example, we will translate the registration page. First, let's define keys and strings with English translation.

lang/en.json

{
"user.name": "Name",
"user.email": "Email",
"user.password": "Password",
"user.password.confirm": "Confirm Password",
 
"register.submit": "Register",
"register.hasAccount": "Already registered?"
}

Then, you can start defining your locale translations with keys and your translations. In this example, we chose the Lithuanian language.

lang/lt.json

{
"user.name": "Vardas",
"user.email": "El. paštas",
"user.password": "Slaptažodis",
"user.password.confirm": "Patvirtinkite Slaptažodį",
 
"register.submit": "Registruotis",
"register.hasAccount": "Jau užsiregistravęs?"
}

Now, we can start updating the Register.vue page to consume these translations. We use the $t helper function and pass the translation key as a parameter.

resources/js/Pages/Auth/Register.vue

<template>
// ...
 
<InputLabel for="name" value="Name" />
<InputLabel for="name" :value="$t('user.name')" />
 
// ...
 
<InputLabel for="email" value="Email" />
<InputLabel for="email" :value="$t('user.email')" />
 
// ...
 
<InputLabel for="password" value="Password" />
<InputLabel for="password" :value="$t('user.password')" />
 
// ...
 
<InputLabel for="password_confirmation" value="Confirm Password" />
<InputLabel for="password_confirmation" :value="$t('user.password.confirm')" />
 
// ...
 
<Link
:href="route('login')"
class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
>
Already registered?
{{ $t('register.hasAccount') }}
</Link>
 
// ...
 
<PrimaryButton class="ml-4" :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
Register
{{ $t('register.submit') }}
</PrimaryButton>
</template>

Now, let's compile everything.

npm run build

And visit the /register page. Changes are not noticeable because the default locale in Laravel is English.

Locale EN

We can try changing Laravel's locale to confirm that translations are working.

config/app.php

'locale' => 'en',
'locale' => 'lt',

After reloading the page, you should see everything translated.

Locale LT

avatar

How to use this $t('some text') in under <script setup> </script> tag?

avatar

Oh. Using trans() helper imported form this package we can. Found this on package doc.

avatar

Hello, Clear tutorial. But how to create a language switcher/toggler for this logic ? Thank you

avatar

This is not something I could tell in a single comment, but we have that implemented on quickadminpanel.com with Vue generator, you might want to look it up.

avatar
صابر طباطبائی یزدی

thank you very much. this template is more valuable than content. because content save one person in one problem. but your activity to help other, promote other to help others. your template is simple. step by step guide to solve a problem. if this template used more, other use it and promote. simplicity is key for sucees. save people time. result is free time to progress to achive the success for all the people.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 66 courses (1167 lessons, total 43 h 18 min)
  • 88 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent New Courses