How to work with laravel, inertia js, and vue-i18n
Published: 2022-03-07 12:11:05

The last week i lost some hours trying to make [inertia js](https://inertiajs.com/) and [vue-i18n](https://kazupon.github.io/vue-i18n/) works together in [changelogfy](https://changelogfy.com). 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/89c91q4lw2ytxmtt17go.png)

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: 

```shell
composer require librenms/laravel-vue-i18n-generator
```

Publish the package configs:

```shell
php artisan vendor:publish --provider="MartinLindhe\VueInternationalizationGenerator\GeneratorProvider"
```

Now let's run this command to convert files:

```shell
php artisan vue-i18n:generate
```

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.

```shell
npm install vue-i18n@next
```

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

```php
<?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()
        ]);
    }
}
```
Now let's set up the **resources/js/app.js**, to use vue-18n and use the current user language send by HandleInertiaRequests middleware.

```javascript
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);
    },
});
```

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>
```

I hope I helped you ✌️