Build multilingual applications with Laravel, Vue 3, React, or Svelte using one set of translation files.

Laravel has always made localization fairly straightforward. You create your language files, define translation keys, and use Laravel’s __() helper wherever you need translated text.

But things become a little different when your frontend uses Inertia.js with Vue, React, or Svelte.

Laravel understands your PHP translation files. Your frontend components don’t automatically have access to them.

And that’s where a simple multilingual feature can start requiring more work than expected.

In this article, I’ll show you how to use your existing Laravel language files directly in Inertia.js components, without maintaining separate translation files for your frontend.

The Problem with Localization in Laravel + Inertia.js

Imagine you’re building a dashboard using Laravel and Vue 3.

In your Laravel application, you have a translation file:

lang/en/messages.php

<?php
return [
'welcome' => 'Welcome back!',
'dashboard' => 'Dashboard',
'settings' => 'Settings',
];

In Laravel, using those translations is easy:

__('messages.welcome');

But what happens when you want the same translation in a Vue component?

<template>
<h1>{{ __('messages.welcome') }}</h1>
</template>

That won’t work automatically. Vue doesn’t know anything about Laravel’s translation files.

You could install a separate internationalization library, maintain JavaScript translation objects, or manually share translations through Inertia middleware.

All these approaches can work.

The problem is that you may end up managing the same text in two different places.

When you add another language or update a translation, you have more files to maintain.

For applications with dozens of pages and hundreds of translation keys, that becomes difficult to manage.

A Simpler Approach: Laravel Lang Sync Inertia

To make this easier, I built an open-source package called Laravel Lang Sync Inertia.

The idea is simple: Laravel already knows which language your application is using, and it already has your translation files.

Why not reuse those translations in your frontend?

With this package, you can select your Laravel translation files and share them with Inertia.js using a single helper:

syncLangFiles('messages');

Your frontend can then access those translations using familiar helpers:

__('messages.welcome')

The package currently supports:

  • Laravel translation files shared through Inertia.js.
  • Vue 3, React, and Svelte frontend components.
  • Dynamic placeholders such as :name.
  • Pluralization using transChoice().
  • Nested translation files and dot-notation keys.
  • Automatic loading based on Laravel’s active locale.
  • TypeScript-compatible frontend helpers.
  • Optional PHP-to-JSON translation export.

Let’s build a working example.

Step 1: Install the Package

First, install the Laravel package using Composer.

composer require erag/laravel-lang-sync-inertia

Next, install its frontend companion package:

npm install @erag/lang-sync-inertia

If your Laravel application doesn’t already have published language files, run:

php artisan lang:publish

Then run the package installation command:

php artisan erag:install-lang

This publishes the package configuration and required assets.

You now have what you need to start sharing Laravel translations with your Inertia frontend.

Step 2: Create Your Language Files

Let’s support English and Hindi in our application.

Inside Laravel’s lang directory, create the following files:

lang/
├── en/
│ └── messages.php
└── hi/
└── messages.php

English: lang/en/messages.php

<?php
return [
'dashboard' => 'Dashboard',
'welcome' => 'Welcome back, :name!',
'settings' => 'Settings',
'notifications' => '{0} No notifications|{1} One notification|[2,*] :count notifications',
];

Hindi: lang/hi/messages.php

<?php
return [
'dashboard' => 'डैशबोर्ड',
'welcome' => 'वापस आने पर स्वागत है, :name!',
'settings' => 'सेटिंग्स',
'notifications' => '{0} कोई सूचना नहीं|{1} एक सूचना|[2,*] :count सूचनाएं',
];

We’re using Laravel’s normal PHP translation structure.

There are no separate JavaScript translation files to maintain.

And if you already have Laravel translations in your project, you can reuse them.

Step 3: Share Translations from Your Laravel Controller

Now open the controller that renders your Inertia page.

For example, DashboardController.php:

<?php
namespace App\Http\Controllers;
use Inertia\Inertia;
use Inertia\Response;
class DashboardController extends Controller
{
public function index(): Response
{
syncLangFiles('messages');
        return Inertia::render('Dashboard');
}
}

That’s the important part:

syncLangFiles('messages');

The helper loads the selected language file based on Laravel’s active locale and shares its translations through Inertia.

You don’t need to create a separate API endpoint or manually pass every translation through your controller response.

You can also share multiple language files when needed:

syncLangFiles([
'messages',
'auth',
'validation',
]);

This is useful for larger applications, where you might have different translation files for authentication, dashboards, settings, and other modules.

Instead of loading everything everywhere, you can choose the files required by each page.

Step 4: Use Laravel Translations in Vue 3

Now let’s display those translations in our Vue dashboard.

Open resources/js/Pages/Dashboard.vue.

<script setup lang="ts">
import { vueLang } from '@erag/lang-sync-inertia';
const { __, trans, transChoice } = vueLang();
</script>
<template>
<main>
<h1>{{ __('messages.dashboard') }}</h1>
        <p>
{{ trans('messages.welcome', {
name: 'Amit'
}) }}
</p>
        <p>{{ __('messages.settings') }}</p>
        <p>
{{ transChoice('messages.notifications', 3) }}
</p>
</main>
</template>

When Laravel’s active locale is English, the page displays:

Dashboard
Welcome back, Amit!
Settings
3 notifications

When the active locale is Hindi, the same component displays:

डैशबोर्ड
वापस आने पर स्वागत है, Amit!
सेटिंग्स
3 सूचनाएं

Notice something important.

We didn’t change the Vue component to support Hindi.

The translation keys remain exactly the same.

Laravel determines the active language, and the package makes the matching translations available to Vue.

That’s the behavior I wanted when building this package.

Step 5: How Language Switching Works

One important thing to understand is that Laravel Lang Sync Inertia uses Laravel’s current locale.

For example:

use Illuminate\Support\Facades\App;
App::setLocale('hi');
syncLangFiles('messages');

This loads the Hindi translations for that request.

For a real application, you would normally store the user’s selected language in a session, user preference, or similar location.

Then, your Laravel middleware can set the locale on each request before the controller loads translations.

The package handles sharing the appropriate translations. Your application remains responsible for deciding which language the user wants.

When Inertia receives updated page props for the new locale, the frontend helpers can use the new translation values.

That keeps language selection separate from translation delivery.

Step 6: What About React and Svelte?

Although we’ve used Vue 3 in this example, the package isn’t limited to Vue.

The Laravel implementation stays the same.

You only need the frontend helper for your chosen framework.

React example

import { reactLang } from '@erag/lang-sync-inertia';
export default function Dashboard() {
const { __, trans } = reactLang();
    return (
<main>
<h1>{__('messages.dashboard')}</h1>
            <p>
{trans('messages.welcome', {
name: 'Amit'
})}
</p>
</main>
);
}

Svelte 5 example

For Svelte, use @inertiajs/svelte v3.

<script module lang="ts">
import { svelteLang } from '@erag/lang-sync-inertia';
    const { __, trans } = svelteLang();
</script>
<main>
<h1>{__('messages.dashboard')}</h1>
    <p>
{trans('messages.welcome', {
name: 'Amit'
})}
</p>
</main>

The translation keys, language files, and Laravel controller remain unchanged.

So whether you build your frontend with Vue, React, or Svelte, you can continue using the same Laravel localization structure.

Step 7: Organizing Translations in Larger Applications

As your application grows, keeping every translation in one file becomes difficult.

You might want a structure like this:

lang/
└── en/
├── auth.php
├── messages.php
└── admin/
├── users.php
└── settings.php

Laravel Lang Sync Inertia supports nested language directories.

For example:

syncLangFiles('admin.users');

Then in Vue:

__('admin.users.title')

This lets you organize translations by feature or module rather than putting everything in a single massive file.

For applications with multiple dashboards, administrative panels, or complex workflows, that organization makes a difference.

Bonus: Export Laravel PHP Translations to JSON

Sometimes you may want actual JSON translation files for a separate frontend workflow or build process.

The package includes an Artisan command for that too:

php artisan erag:generate-lang

By default, it generates frontend-ready JSON files under:

resources/js/lang/

The source and output paths can be customized in config/inertia-lang.php.

This feature is optional. You don’t need to generate JSON files to use the normal Inertia translation-sharing workflow.

Why Not Just Use Vue I18n?

That’s a fair question.

Vue I18n is a mature solution with capabilities that extend beyond simply sharing Laravel translations. If your application already has a frontend-specific internationalization architecture, it might be exactly what you need.

Laravel Lang Sync Inertia solves a more focused problem.

If Laravel is already your source of truth for translations, you may not want to maintain another set of language files just for Vue.

With this package, Laravel continues managing translation data, while Inertia makes selected translations available to the frontend.

It isn’t about replacing every internationalization library.

It’s about removing duplicated work for developers using Laravel and Inertia together.

A Few Things Worth Remembering

Before using localization in a production application, keep a few practical details in mind:

  • Make sure the requested locale is supported by your application.
  • Use a middleware or another per-request mechanism to restore the user’s selected locale.
  • Share only the translation groups needed by your page.
  • Prefer Laravel’s :name placeholder syntax for new translations.
  • When changing languages, ensure Inertia receives fresh page props for the selected locale.

These small decisions make multilingual applications easier to maintain as they grow.

Final Thoughts

Adding another language to an application shouldn’t mean rewriting the same translations in multiple places.

If you’re already using Laravel with Inertia.js, you have most of the localization infrastructure you need.

The missing piece is making those translations available to your frontend components in a clean, consistent way.

That’s why I created Laravel Lang Sync Inertia.

It’s open source, and I hope it saves other Laravel developers some of the repetitive setup involved in building multilingual applications.

If you’re working with Laravel, Vue 3, React, or Svelte, give it a try.

Resources

If you find it useful, consider starring the GitHub repository. And if you run into an issue or have an idea for improvement, feel free to open an issue.

Thanks for reading!

— Amit Gupta