Laravel’s localization features provide a convenient way to retrieve strings in various languages, allowing us to support the multiple languages within your application quickly. Language strings are stored in the files within the resources/lang directory. In addition, there should be a subdirectory for each language supported by the application within that directory.
We will create the middleware to check if the locale is set, then change the application’s locale.
Step 1: Install Laravel
laravel new localization
or
composer create-project laravel/laravel localization
By default, our application’s local language is English or en.
You can find it on the config >> app.php file.
// app.php /* |-------------------------------------------------------------------------- | Application Locale Configuration |-------------------------------------------------------------------------- | | The application locale determines the default locale that will be used | by the translation service provider. You are free to set this value | to any of the locales which will be supported by the application. | */ 'locale' => 'en',
Here, the locale is set to en.
Now, if you check the resources >> lang folder, there is one folder called en, with some files like auth.php, pagination.php, passwords.php, and validation.php.
So, these files are translation files. But first, let’s check the auth.php file.
<?php // auth.php return [ /* |-------------------------------------------------------------------------- | Authentication Language Lines |-------------------------------------------------------------------------- | | The following language lines are used during authentication for various | messages that we need to display to the user. You are free to modify | these language lines according to your application's requirements. | */ 'failed' => 'These credentials do not match our records.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', ];
This file returns an array that has key-value pair. So, here you can define any key you like, but the values are on your language-specific statements.
An app.php file’s root folder name is en, so translation to these file’s statement is in English or en. If the root folder is fr means French translation, then the app.php file might look like below.
<?php // auth.php return [ /* |-------------------------------------------------------------------------- | Authentication Language Lines |-------------------------------------------------------------------------- | | The following language lines are used during authentication for various | messages that we need to display to the user. You are free to modify | these language lines according to your application's requirements. | */ 'failed' => 'Ces informations d'identification ne correspondent pas à nos enregistrements', 'throttle' => 'Trop de tentatives de connexion. Veuillez réessayer dans: secondes secondes.', ];
Remember, you need to add the same keys for all your translation files across the different languages and change the values respective to your languages.
In the above code, we have written two items: failed and throttle, and the values are translated into French.
So, when the user changes the languages, these statements will be displayed because, in the view file, we will call it by its key, and due to middleware, it will map to the correct languages.
Step 2: Creating Translation Files
Now we will go for three languages. English is already there.
- French
- Spanish
- Japanese
Let’s create a folder inside the resources >> lang folder.
Create a file called sentence.php and add the following code inside all four folders.
For en >> sentence.php file,
<?php // sentence.php return [ 'welcome' => 'Welcome Friend' ];
For es >> sentence.php file,
<?php // sentence.php return [ 'welcome' => 'Bienvenido amigo' ];
For fr >> sentence.php file,
<?php // sentence.php return [ 'welcome' => 'Bienvenue mon ami' ];
And last, jp >> sentence.php file.
<?php // sentence.php return [ 'welcome' => 'ようこそ友達' ];
You can put as many texts as you want. I have just taken one text for this demo.
Now that we have placed all translations, let’s start working on the views and make our application load the above translations.
Step 3: Set up the view
Create a layouts folder inside the resources >> views folder, and inside that layouts folder, create an app.blade.php file and add the following code.
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!-- Scripts --> <script src="{{ asset('js/app.js') }}" defer></script> <!-- Fonts --> <link rel="dns-prefetch" href="//fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css"> <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> </head> <body> <div id="app"> <nav class="navbar navbar-expand-md navbar-light navbar-laravel"> <div class="container"> <a class="navbar-brand" href="{{ url('/') }}"> {{ config('app.name', 'Laravel') }} </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <!-- Left Side Of Navbar --> <ul class="navbar-nav mr-auto"> </ul> <!-- Right Side Of Navbar --> <ul class="navbar-nav ml-auto"> <li class="nav-item dropdown"> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> Language <span class="caret"></span> </a> <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="lang/en"><img src="{{asset('img/us.png')}}" width="30px" height="20x"> English</a> <a class="dropdown-item" href="lang/fr"><img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French</a> <a class="dropdown-item" href="lang/es"><img src="{{asset('img/es.png')}}" width="30px" height="20x"> Spanish</a> <a class="dropdown-item" href="lang/jp"><img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese</a> </div> </li> </ul> </div> </div> </nav> <main class="py-4"> @yield('content') </main> </div> </body> </html>
Open your welcome.blade.php file, which is by default inside the resources >> views folder, and place below code, including a markup just for a languages dropdown.
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-body"> hello </div> </div> </div> </div> </div> @endsection
Step 4: Setup route, controller, and middleware
Inside routes >> web.php, add the following route.
Route::get('lang/{locale}', 'HomeController@lang');
Define a lang method inside the HomeController.php file. For example, you can create a controller using the following command.
php artisan make:controller HomeController
Write the following code inside that file.
<?php // HomeController.php namespace App\Http\Controllers; use Illuminate\Http\Request; use App; class HomeController extends Controller { public function lang($locale) { App::setLocale($locale); session()->put('locale', $locale); return redirect()->back(); } }
This function will see the locale and put it into the session.
Now, create a middleware using the following command.
php artisan make:middleware Localization
It will create a file inside the app >> Http >> Middleware folder.
Now open your newly created middleware file called Localization.php and update the handle method with the below code. So, our final file looks like below.
<?php // Localization.php namespace App\Http\Middleware; use Closure; use App; class Localization { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (session()->has('locale')) { App::setLocale(session()->get('locale')); } return $next($request); } }
Step 5: Register the Localization Middleware
Now add the middleware in App\Http\Kernel’s $ middlewareGroup’s array like so.
protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\Localization::class, ], 'api' => [ 'throttle:60,1', 'bindings', ], ];
Now, one final thing is remaining. Add the following code inside the resources >> views >> layouts >> app.blade.php file.
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!-- Scripts --> <script src="{{ asset('js/app.js') }}" defer></script> <!-- Fonts --> <link rel="dns-prefetch" href="//fonts.gstatic.com"> <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css"> <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> </head> <body> <div id="app"> <nav class="navbar navbar-expand-md navbar-light navbar-laravel"> <div class="container"> <a class="navbar-brand" href="{{ url('/') }}"> {{ config('app.name', 'Laravel') }} </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <!-- Left Side Of Navbar --> <ul class="navbar-nav mr-auto"> </ul> <!-- Right Side Of Navbar --> <ul class="navbar-nav ml-auto"> @php $locale = session()->get('locale'); @endphp <li class="nav-item dropdown"> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> Language <span class="caret"></span> </a> @switch($locale) @case('fr') <img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French @break @case('es') <img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Spain @break @case('jp') <img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese @break @default <img src="{{asset('img/us.png')}}" width="30px" height="20x"> English @endswitch <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="lang/en"><img src="{{asset('img/us.png')}}" width="30px" height="20x"> English</a> <a class="dropdown-item" href="lang/fr"><img src="{{asset('img/fr.png')}}" width="30px" height="20x"> French</a> <a class="dropdown-item" href="lang/es"><img src="{{asset('img/es.png')}}" width="30px" height="20x"> Spanish</a> <a class="dropdown-item" href="lang/jp"><img src="{{asset('img/jp.png')}}" width="30px" height="20x"> Japanese</a> </div> </li> </ul> </div> </div> </nav> <main class="py-4"> @yield('content') </main> </div> </body> </html>
If we change the language in the above code, the dropdown still shows Language instead of the current locale. We can fix this by adding a switch statement and checking what locale we have, and based on that, we will show the current locale with a flag icon like below.
Finally, add the following code inside the resources >> views >> welcome.blade.php file.
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-body"> <p>{{ trans('sentence.welcome')}}</p> </div> </div> </div> </div> </div> @endsection
I have used the trans() function, which takes one argument, the filename.array_key_name.
If you have done all correctly till now, go to the root route inside the browser, and you will see the dropdown with the four languages.
Select the language, and you will see the welcome message in a different language.
That’s it for this tutorial.

Krunal Lathiya is a seasoned Computer Science expert with over eight years in the tech industry. He boasts deep knowledge in Data Science and Machine Learning. Versed in Python, JavaScript, PHP, R, and Golang. Skilled in frameworks like Angular and React and platforms such as Node.js. His expertise spans both front-end and back-end development. His proficiency in the Python language stands as a testament to his versatility and commitment to the craft.
Using session as your locale is not good for SEO.
What do you recommend
Thank you for this tutorial.
how setup this in web.php route file
localhost:8000 which get lang strings from resources/lang/en directory
localhost:8000/en default which get lang strings from resources/lang/en directory
localhost:8000/ar which get lang strings from resources/lang/ar directory
One issue I had and have since fixed, is that the links for changing the language need to be absolute to work on every page. I had some pages with URLs like ‘example.com/one/two’, and when i clicked on the link to change the language it redirected me to the URL ‘example.com/one/lang/en’ – which does not exist and just gives a 404. To fix this just make your language changing links absolute.
Before (doesn’t work on all pages)
English
After (notice the forward slash before ‘lang’) – WORKS
English
Other than that thank you for an amazing tutorial!
this post very helpfull to me thank you sir
It’s a grate article. Please also tell me, how do I translate values coming from database.
Thank you save my day
thank @Krunal it is very helpfull
It’s a great tutorial.
I having a problem making a CRUD with the multilanguage website
when i make the edit button it say missing parameters, i doing that way:
{{ route(‘user.edit’, $user->id, App()->getLocale()) }}
great
your solution works but how do we make changes to URL when we switch the language? Eg: when we switch from English ‘en’ to Hindi ‘hi’ the URL should also change. like /en/posts to /hi/posts !
Thanks for help, man 😀