Article
Translate Laravel Jetstream and Inertia
How to translate a new projet based on Laravel Jetstream and InertiaJs with vue-i18n or Matice ? Discover all possibilities !
In order to translate the various contents included in Laravel and Jetstream, the package laravel-lang/lang gives us pre-made file that we can copy/paste. We only have left the translation of our Vue files.
To do this, we have 2 options :
- Only manage our translation server-side. Which is done with GENL/Matice.
- Split the front-end / back-end translations and then use the package vue-i18n
Depending on your team's size or its ability to evolve, you have to pick one solution. Matice is an easy fit for a team used to Blade / Laravel because it works the same as functions in PHP. The package is still young, and multilingual lazy loading is not available yet : you choose in a config file the languages you want to include. This is only a concern if your project handle a large number of languages or translations.
On the other hand, vue-i18n is the most popular translation solution in Vue projects, but doesn't offer any specific integration for Laravel.
Use GENL/Matice
We add the composer package :
composer require genl/matice
We add the @translations
directive in our app.blade.php file before our JS files loading.
On the JS side, a package is also available to add translations functions, inspired by Laravel:
npm install matice --save-dev
Then, the functions and their parameters are explained in the project's README et are similar to Laravel.
tUse Vue-i18n
Install Vue-i18n in a Laravel Jetstream project
For vue-i18n, the solution is only in the front-end.
npm i --save-dev vue-i18n@next
In order to use JSON files or translations in Vue files, it is mandatory to add @intlify/vue-i18n-loader and to configure webpack.
npm i --save-dev @intlify/vue-i18n-loader@next
In webpack.config.js
:
module: {
rules: [
{
test: /\\.vue$/,
loader: 'vue-loader',
},
{
test: /\\.(json5?|ya?ml)$/, // target json, json5, yaml and yml files
type: 'javascript/auto',
loader: '@intlify/vue-i18n-loader',
include: [ // Use `Rule.include` to specify the files of locale messages to be pre-compiled
path.resolve(__dirname, 'src/locales')
]
},
{
resourceQuery: /blockType=i18n/,
type: 'javascript/auto',
loader: '@intlify/vue-i18n-loader'
},
]
}
Use of Vue-i18n in a Laravel Jetstream project
We now only have to add vue-i18n to our Vue Instance.
To do this, we modify app.js
.
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
locale: 'fr',
fallbackLocale: 'fr',
messages: {
fr
}
});
// ajouter après .use(InertiaPlugin)
.use(i18n)
We are then allowed to create i18n blocks directly in a component :
<i18n locale="fr">{
"forgot_password": "Mot de passe oublié?",
"login": "Se connecter",
"remember_me": "Se souvenir de moi"
}</i18n>
Otherwise, we can put our translations into a JS file.
export default {
"agree": "J'accepte les {tos} et la {privacyPolicy}",
"email": "Email",
"name" : "Raison sociale",
"password": "Mot de passe",
}
Our install makes accessible a this.$t()
function in our components which uses as parameters the translation key et brings back the content according to the defined language.
For example :
<jet-label for="password_confirmation" :value="$t('confirm_password')" />
Sometimes, this is not enoughI want to display the message
"I accept the Terms of Service and Privacy Policy" and create links to 2 different pages.
For complex situations, vue-i18n allows to create a i18n-t tag, which in out example will replace {tos}
and {privacyPolicy}
by the templates. In the translation, we just have to write
"agree": "I accept the {tos} and {privacyPolicy}"
.
<i18n-t keypath="agree">
<template #tos>
<a target="_blank" :href="route('terms.show')" class="underline text-sm text-gray-600 hover:text-gray-900">noparse_b262f3093d421b0598f49ae543c45a43</a>
</template>
<template #privacyPolicy>
<a target="_blank" :href="route('policy.show')" class="underline text-sm text-gray-600 hover:text-gray-900">noparse_0b056d589fb911d197db8823ab246b2b</a>
</template>
</i18n-t>