The “locale” variable will contain the user’s current language choice.
The “language” variable will store the JSON translations used by the frontend.
// Providers/AppServiceProvider.php use Inertia\Inertia; public function boot() { Inertia::share([ 'locale' => function () { return app()->getLocale(); }, 'language' => function () { return translations( resource_path('lang/'. app()->getLocale() .'.json') ); }, ]); }
Add translations Function TO PHP helper function
This function returns the JSON translation file used in the language variable above.
// app/helpers.php <?php function translations($json) { if(!file_exists($json)) { return []; } return json_decode(file_get_contents($json), true); } ?>
We should add the helper file to composer.json file.
// composer.json "autoload": { // ... "files": [ "app/helpers.php" ] },
After adding it “composer dump-autoload” terminal command should be run in the root of the Laravel application. (Keep in mind: If you deploy the changes to server you may need to run this command on the server too.)
Language Switching component
We need a Vue component so that the user can toggle their language preference. The selectable_locale defines the language choice using the two-letter language code.
I am using tailwind styles. You can change the styling according to your needs.
// resources/js/Language/LanguageSelector.vue <template> <div class="ml-4"> <inertia-link :href="route('language', [selectable_locale])" :class="classes"> <div v-if="selectable_locale == 'fr'">FR</div> <div v-else>EN</div> </inertia-link> </div> </template> <script> export default { computed: { selectable_locale() { if(this.$page.locale == 'fr') { return 'en'; } return 'fr' }, classes() { return 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-red-900 hover:text-red-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out' } }, } </script>
Route
We have an inertia link to the “/language” route. It is needed to be added in web.php.
// routes/web.php Route::get('/language/{language}', function ($language) { Session()->put('locale', $language); return redirect()->back(); })->name('language');
Check:
php artisan route:list
if language is not in the list we need to run:
php artisan route:cache
Now we can import LanguageSelector component into our AppLayout.vue file.
// path/of/your/layout/view/AppLayout.vue // ... import LanguageSelector from '@/Language/LanguageSelector' export default { components: { // ... LanguageSelector, }, // ...
Language Setting Middleware
We need to add middleware to check that value on each page request and make sure we pass the correct variable to the view.
If we want to use our application’s default language here is our solution:
// Http/Middleware/SetLocale.php namespace App\Http\Middleware; use Closure; class SetLocale { public function handle($request, Closure $next) { app()->setLocale(config('app.locale')); if(session()->has('locale')) { app()->setLocale(session('locale')); } return $next($request); } }
Otherwise, we can use the browser’s language so that the users can see the page automatically with their preferred language. Here is the solution:
// Http/Middleware/SetLocale.php namespace App\Http\Middleware; use Closure; use Session; use App; use Config; class SetLocale { public function handle($request, Closure $next) { if (Session::has('locale')) { $locale = Session::get('locale', Config::get('app.locale')); } else { $locale = substr($request->server('HTTP_ACCEPT_LANGUAGE'), 0, 2); if ($locale != 'fr' && $locale != 'en') { $locale = 'en'; } } App::setLocale($locale); return $next($request); } }
Register SetLocale Middleware
Next, register the middleware. Ensure it is registered after we have initialized Laravel’s Session middleware.
// Http/Kernel.php protected $middlewareGroups = [ 'web' => [ // ... \App\Http\Middleware\SetLocale::class, // ... ], ]; protected $middlewarePriority = [ // ... \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\SetLocale::class, // ... ];
Register vue.js helper mixin file for translating
This registers our vue.js mixins required for translating the JSON file on the frontend.
// resources/js/app.js Vue.mixin(require('./base'))
Add helper mixins to base.js
Add the mixins below, the first method is for translating a normal string, the last is for translating a string with basic pluralization.
// resources/js/base.js module.exports = { methods: { /** * Translate the given key. */ __(key, replace = {}) { var translation = this.$page.language[key] ? this.$page.language[key] : key Object.keys(replace).forEach(function (key) { translation = translation.replace(':' + key, replace[key]) }); return translation }, /** * Translate the given key with basic pluralization. */ __n(key, number, replace = {}) { var options = key.split('|'); key = options[1]; if(number == 1) { key = options[0]; } return tt(key, replace); }, }, }
Add JSON translation file
Next, we need to add the JSON translation file in lang folder. For my case it is fr.json.
You can find all laravel language files from https://github.com/Laravel-Lang/lang
In the fr.json file we can add all the translations we need for our application. Here is the basic example:
// resources/lang/fr.json { "Status": "Statut", "Location": "Lieu", "Title": "Titre", "Name": "Nom", "Email": "Email", "Phone": "Téléphone", "phone number": "numéro de téléphone", // ... }
Translate the application
Next, we will need to go through our application and translate it. We need to edit all of our vue pages.
Check if all is done
To have the whole app translated the following tasks need to be completed.
- All the strings in the resources/js/ would need to be translated and placed in fr.json.
- If you are using mail notifications (e.g. password reset) those also need to be added to fr.json. (See https://github.com/Laravel-Lang/lang json folder)
- The contents of resources/lang/en need to be duplicated into resources/lang/fr and translated. (See https://github.com/Laravel-Lang/lang src folder)
I summarized this article from the source:
https://devonmather.xyz/localizing-a-laravel-app-using-vue-js-and-inertia-js-without-any-dependencies/