Click Below to subscribe

How to Implement localization in Laravel 2021

Laravel's localization feature provides a convenient way to localize our web application. In this article, we will implement localization step by step.

1. Let's create a new laravel project.

composer create-project laravel/laravel laravel-localization

Note:- In this tutorial, we will use bootstrap free pricing template - Pricing example for Bootstrap (getbootstrap.com)

2. After creating our project integrate the above html template.(checkout github repo)

3.  Create a route for handling language switching. In this route, we are simply putting user selected locale(language) in session and redirect back to the webpage. (routes/web.php)

Note:-  you can also use import statement use Session; on top instead of \Session; both are same.

Route::get('setlocale/{locale}', function($lang) {
    \Session::put('locale', $lang);
    return redirect()->back();
});

4. We need a middleware for translating pages according to our session locale (user selected). so let's create a middleware.

php artisan make:middleware LanguageSwitcher

go to app/Http/Middleware and this middleware LanguageSwitcher.php.

5. We need to modify the handle function.

<?php

namespace App\Http\Middleware;

use Closure;
use Session;
use App;
use Config;
class LanguageSwitcher
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (!Session::has('locale'))
         {
           Session::put('locale',Config::get('app.locale'));
        }
        App::setLocale(Session::get('locale'));
        return $next($request);
    }
}

#Logic in middleware:

In this middleware, we are checking the value of locale session variable. If the value of this variable is empty in session we will set locale value to default locale which is set(hardcoded) in the config file (config/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',

so that's why 

 if (!Session::has('locale')) {
     Session::put('locale', Config::get('app.locale'));
 }

else if session has locale variable means if it's not empty then if block is not executed.

so on both cases now we have locale variable value in the session. so we can get the value and set it to App locale.

App::setLocale(Session::get('locale'));

6. Now we need to register this middleware in the kernel. Open app/Http/kernal.php and inside 

$routeMiddleware array add LanguageSwitcher
/**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'language' => \App\Http\Middleware\LanguageSwitcher::class,
    ];

7. For serving this middleware we need a route group. so each request goes through this middleware. (routes/web.php)

Route::group(['middleware'=>'language'], function () {
    Route::get('/', function () {
        return view('home');
    });
});

8. Now we need to create our translation files. by default, laravel provides a few files for the english translation. (resources/lang/en)

let's create files for the french language. simply create a new folder fr and create messages.php file in en and fr folder.

/resources
    /lang
        /en
            messages.php
        /fr
            messages.php 

Note: In this tutorial, I am using single file messages.php but you can use multiple files based on your requirement.

9. Now we need to update our translation based on our view(html).

//en/messages.php
<?php

return [
    'plan_title' => 'Pricing',
    'plan_text' => 'Pick a plan that suits you.',
    'free' => 'Free',
    'pro' => 'Pro',
    'month' => 'month',
    'enterprise' => 'Enterprise',
    'users_included' => ':total users included',
    'storage_included' => ':total GB of storage',
    'email_included' => ':total email account'
];

//fr/messages.php
<?php

return [
    'plan_title' => 'Prix',
    'plan_text' => 'Choisissez un plan qui vous convient.',
    'free' => 'libre',
    'pro' => 'Pro',
    'month' => 'mois',
    'enterprise' => 'Enterprise',
    'users_included' => ':total utilisateurs inclus',
    'storage_included' => ':total Go de stockage',
    'email_included' => ':total compte de messagerie'
];

Note: for the dynamic value, we are using :(colon)

10. Now we need to create a select box so users are able to switch languages.

<nav class="d-inline-flex mt-2 mt-md-0 ms-md-auto">
    <span class="me-3 py-2 text-dark">
        <select class="form-select form-select-sm language-switcher">
            <option value="en" @if(App::getLocale() == 'en') selected @endif>English</option>
            <option value="fr" @if(App::getLocale() == 'fr') selected @endif>French</option>
        </select>
    </span>
</nav>

Note: for showing the currently selected language we can use App::getLocale() as in the above code.

12. Now we need to redirect our browser to setlocale route. so we need to handle the change of this selectbox.

<script>
    $(document).on('change', '.language-switcher', function() {
        window.location.href = "{{ url('setlocale') }}" + '/' + $(this).val();
    })
</script>

 Note: I am using jquery you can also use javascript addEventListener.

In the above js code when the user selects any language we will get that language by $(this).val(). so for example, if he/she selected fr

then our browser redirected to http://localhost/setlocale/fr

13. Now we need to replace our hardcoded text with laravel helper function. laravel provides multiple helper functions for handling translation. In this article we gonna focus on __() and trans() functions.

both functions take three arguments two are optional.

__(key, array, locale)
__('plan_title')  --> Pricing

trans(key, array, locale)
trans('plan_title')  --> Pricing

If we need to pass any dynamic data into our translation then we need a second argument.

// suppose messages.php
<?php

return [
 'welcome' => 'Hello :name',
];

trans('messages.welcome', [ 'name' => 'akash' ]); 
__('messages.welcome',    [ 'name' => 'akash' ]);
// both gives you "Hello akash"

If you need any specific locale translation then we use third argument.

// suppose we need french translation
trans('messages.welcome', [ 'name' => 'akash' ], 'fr'); 
__('messages.welcome',    [ 'name' => 'akash' ], 'fr');
// both gives you "Bonjour akash"

14. Finally open views of our project and replace hardcoded text with these functions.

@extends('layouts.main')

@section('title', 'Home')

@section('content')
<div class="pricing-header p-3 pb-md-4 mx-auto text-center">
    <h1 class="display-5 fw-normal">{{ __('messages.plan_title') }}</h1>
    <p class="fs-5 text-muted">{{ __('messages.plan_text') }}</p>
</div>
<main>
    <div class="row row-cols-1 row-cols-md-3 mb-3 text-center">
        <div class="col">
            <div class="card mb-4 rounded-3 shadow-sm">
                <div class="card-header py-3">
                    <h4 class="my-0 fw-normal">{{ __('messages.free') }}</h4>
                </div>
                <div class="card-body">
                    <h1 class="card-title pricing-card-title">$0<small class="text-muted fw-light">/{{ __('messages.month') }}</small></h1>
                    <ul class="list-unstyled mt-3 mb-4">
                        <li>{{ __('messages.users_included', ['total' => 10]) }}</li>
                        <li>{{ __('messages.storage_included', ['total' => 2]) }}</li>
                        <li>{{ __('messages.email_included', ['total' => 1]) }}</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="col">
            <div class="card mb-4 rounded-3 shadow-sm">
                <div class="card-header py-3">
                    <h4 class="my-0 fw-normal">Pro</h4>
                </div>
                <div class="card-body">
                    <h1 class="card-title pricing-card-title">$15<small class="text-muted fw-light">/{{ __('messages.month') }}</small></h1>
                    <ul class="list-unstyled mt-3 mb-4">
                        <li>{{ __('messages.users_included', ['total' => 20]) }}</li>
                        <li>{{ __('messages.storage_included', ['total' => 10]) }}</li>
                        <li>{{ __('messages.email_included', ['total' => 5]) }}</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="col">
            <div class="card mb-4 rounded-3 shadow-sm border-primary">
                <div class="card-header py-3 text-white bg-primary border-primary">
                    <h4 class="my-0 fw-normal">Enterprise</h4>
                </div>
                <div class="card-body">
                    <h1 class="card-title pricing-card-title">$29<small class="text-muted fw-light">/{{ __('messages.month') }}</small></h1>
                    <ul class="list-unstyled mt-3 mb-4">
                        <li>{{ __('messages.users_included', ['total' => 30]) }}</li>
                        <li>{{ __('messages.storage_included', ['total' => 15]) }}</li>
                        <li>{{ __('messages.email_included', ['total' => 10]) }}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</main>
@endsection

open the project in the browser and try to switch language.

Checkout my full laravel localization example.

https://github.com/ultimateakash/laravel-localization

If you facing any issues. please post a comment. i will be happy to help you,
Thanks

Leave Your Comment