As per usual, the practical stuff (Implementation) comes first to keep this short for those who are in a hurry, giving you the bottom line first ! then the things you need to know, then the things you don’t need to know, the one exception in this post is the first paragraph after this one, so let’s dive right in
What is different in Laravel 9 ?
The only difference between Laravel 8 an 9 in localization is that in Laravel 9, we no longer store language files in resources/lang, but rather in the new lang directory
So, there are 2 methods of creating language files, which one you should use depends on how much translation of hard coded strings there is on your website, if you only have a little, you would use a method called “1- Short strings” which is the older method, and starting from Laravel 5.4 we also have the “Translation strings” method which uses JSON and is better suited for websites where hard coded strings are many
Can i use both methods at the same time ?
Yes you can, but there is no reason to that i can think of
Implementation
So, unlike everywhere else, to get you up to speed, I will start with the newer method (the one you will likely use), then go back to the older short string method
I am assuming you already created a Laravel 9 project
1- Configure the default locale and the fallback_locale of your website as well as adding the available_locales in (config/app.php), Default is the language that your website starts with, and fallback is the language Laravel should look at when it fails to find a string, there is a third fallback within your view that you will discover in Just a bit.
For the sake of example, I am using the default local of ‘ar’ and the fallback locale of ‘en’, put those into my config file, specify the two languages the website will support and get on with the next step, my config is included here for convenience
'locale' => 'ar',
'fallback_locale' => 'en',
'available_locales' => [
'English' => 'en',
'Arabic' => 'ar',
],
2- Create the Locale files, /lang/en.json
and /lang/ar.json
3- Middleware: So, now that we have the above setup, we need middleware so that the user can specify a locale that would persist ! Obviously, you can specify this manually inside a route or something, but you would probably rather use a middleware instead of having different URLs (Unimportant note: not necessarily, it would depend on how your website functions, sometimes it is better to have a different language version for every url for SEO for example, but that requires separation of languages in your user content in the database, and is for another day)
php artisan make:middleware Localization
INFO Middleware [app/Http/Middleware/Localization.php] created successfully.
Now, we have new middleware file in /app/Http/Middleware/Localization.php
, Localization ! but how do we use it ? Up to now this middleware does nothing, but we want it to fire up on every page request, to do that, we need to add it to /app/http/Kernel.php
, so in that file, in the protected $middlewareGroups array, and the web inner array, Add the following line
\App\Http\Middleware\Localization::class,
So our middleware now fires up with every page load ! this is so that after we modify the middleware, we can make sure the page uses the locale the user has set. but before we get to making that middleware, how will the user set his/her preferred locale ? So, let us start by creating the middleware, to make it work, add the following two lines to include the relevant Facades
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;
And the following lines within the handle method, right above the return statement
if (Session::has('locale')) {
App::setLocale(Session::get('locale'));
}
Now, the last thing to do that will make it work (But not necessarily how we want it to work on our website) is to add a route to do that, here, I am using an anonymous function/closure, but feel free to use a controller if you like (Not really much code to warrant it’s own controller in my opinion)
Route::get('language/{locale}', function ($locale) {
app()->setLocale($locale);
session()->put('locale', $locale);
return redirect()->back();
});
Now, to making the website use those languages
X: Using the language strings !
As you might remember form the part numbered (1) above, I told you that there is a third fallback besides the one in the config file, which is in the blade view itself !
To use any string, the syntax in the website is {{ __(‘Welcome to our website’) }}, if the JSON does not contain such a string, the litteral itself is used ! so even if this string (Welcome to our website) is nowhere to be found in any language file, it is still printed as (Welcome to our website) !
With that out of the way, once you have a few of those strings on the website, visiting the URL /language/ar will flip the website to Arabic, you can browse around the website, and for as long as your session cookie is there, it will work ! going back to /language/en will switch it to English in the same manner !
This is not really the thing we are looking for, we want the user to seamlessly switch between languages via drop-down or button right ? so here we go