DEV Community

Cover image for How to work with laravel, inertia js, and vue-i18n
Paulo Castellano
Paulo Castellano

Posted on • Updated on • Originally published at paulocastellano.com

How to work with laravel, inertia js, and vue-i18n

The last week i lost some hours trying to make inertia js and vue-i18n works together in changelogfy. But some people from inertiajs discord community help to understand and make it works, very thanks 🙏

To help some people to understand the process, I decided to create this post blog.

I will centralize all my languages files at laravel default translates, in the folder resources/lang.

laravel lang folder

I think is a great way to deliver i18n to the front and backend with the same translated files.

But vuejs requires JSON language files, not PHP.

To convert all our PHP translate files to JSON, we will install the composer package bellow:

composer require librenms/laravel-vue-i18n-generator
Enter fullscreen mode Exit fullscreen mode

Publish the package configs:

php artisan vendor:publish --provider="MartinLindhe\VueInternationalizationGenerator\GeneratorProvider"
Enter fullscreen mode Exit fullscreen mode

Now let's run this command to convert files:

php artisan vue-i18n:generate
Enter fullscreen mode Exit fullscreen mode

A file will be created by default in resources/js/vue-i18n-locales.generated.js

This file contains all your languages.

Important:
You need run the command above every time you added new translations or every deployment of your application!

Now let's install the vue-i18n package.

npm install vue-i18n@next
Enter fullscreen mode Exit fullscreen mode

If you like to give power to user changes automatically your language, you can send locale to view by HandleInertiaRequests middleware.

<?php

namespace App\Http\Middleware;

use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Inertia\Middleware;

class HandleInertiaRequests extends Middleware
{
    protected $rootView = 'app';

    public function version(Request $request)
    {
        return parent::version($request);
    }

    public function share(Request $request)
    {
        return array_merge(parent::share($request), [
            'user' => function () use ($request) {
                if (!$request->user()) {
                    return;
                }
            },
            'locale' => app()->getLocale()
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

Now let's set up the resources/js/app.js, to use vue-18n and use the current user language send by HandleInertiaRequests middleware.

import { createI18n } from "vue-i18n";
import localeMessages from "./vue-i18n-locales.generated";

import { createApp, h } from "vue";
import { createInertiaApp } from "@inertiajs/inertia-vue3";

createInertiaApp({
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        const i18n = createI18n({
            locale: props.initialPage.props.locale, // user locale by props
            fallbackLocale: "en", // set fallback locale
            messages: localeMessages, // set locale messages
        });

        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .use(i18n)
            .mixin({
                methods: {
                    route
                },
            })
            .mount(el);
    },
});
Enter fullscreen mode Exit fullscreen mode

Now you can use vue-18n in any view like this:

<template>
    <h1>
        {{ t("home.title") }}
    </h1>
</template>
<script>
import { useI18n } from "vue-i18n";
export default {
    setup() {
        const { t } = useI18n({});
        return { t };
    },
}
</script>
Enter fullscreen mode Exit fullscreen mode

I hope I helped you ✌️

Top comments (6)

Collapse
 
wilpat profile image
William Okafor • Edited

Thanks for the walkthrough.

If you're trying to follow this tutorial, I'd suggest you use this package instead as laravel-vue-i18n-generator package is no longer being maintained.

Compiled language file name is different but the underlying logic is the same.

An alternative might be to store the languages as a json file instead and then load this into the HandleInertiaRequests class based off the current locale.

For instance:

Add this into the class

private function getTranslationFile($code)
    {
        $jsonString = [];
        if (File::exists(base_path('<your-lang-folder>/'.$code.'.json'))) {
            $jsonString = file_get_contents(base_path('lang/'.$code.'.json'));
            $jsonString = json_decode($jsonString, true);
        }

        return $jsonString;
    }
Enter fullscreen mode Exit fullscreen mode

Then update the share method to include:

return array_merge(parent::share($request), [
            ...
            'content' => $this->getTranslationFile(session()->get('locale') ?? 'en'),
            ...
        ]);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
paulocastellano profile image
Paulo Castellano

Hi @wilpat

Thanks for your contribution, but I believe you confused the packages, i mentioned this:

github.com/librenms/laravel-vue-i1...

And i think you found this:
github.com/martinlindhe/laravel-vu...

It's a fork, almost the same name, yes it's confused rs.

But the package it's updated and keeps working well, I created a new project with laravel 9 and tested it, and it's running.

Collapse
 
dsampaolo_95 profile image
Didier Sampaolo

Hi Paulo, thank you very much for this post. The last section disappeared. Bummer, it's the one explaining how to user vue-i18n in my views. :D

Collapse
 
paulocastellano profile image
Paulo Castellano

Hi @didier really the content disappeared!

I updated the article again, but you can check the original post here:

paulocastellano.com/blog/how-to-wo...

Collapse
 
arkanius profile image
Victor Gazotti

Awesome!

Collapse
 
paulocastellano profile image
Paulo Castellano

Thanks!