DEV Community

Cover image for Adding multi-language functionality in a website developed in laravel.
fadilxcoder
fadilxcoder

Posted on

Adding multi-language functionality in a website developed in laravel.

Hello Everyone,
Today I will share with you how do add multi language to a website that was developed in laravel, my version is 5.6 but it will work on 5.7 as well.

So...here we go!

First of all, I assume that you already have a working version of laravel. Navigate to that particular folder and open your terminal or command prompt.

Run the following command in order to create the required middleware.

$ php artisan make:middleware Localization

Enter fullscreen mode Exit fullscreen mode

Then open it. The file should be in "project_name/app/Http/Middleware/Localization.php"

Update the code that is present with the one below :

public function handle($request, Closure $next)
{
   if(\Session::has('locale'))
   {
       \App::setlocale(\Session::get('locale'));
   }
   return $next($request);
}

Enter fullscreen mode Exit fullscreen mode

Lets say you want your website to be in English and French.

  1. Go to "project_name/resources/lang/en/"

  2. Create a file name "messages.php"

  3. Create folder "fr" in "project_name/resources/lang/"

  4. Create a file name "messages.php" in "project_name/resources/lang/fr/"

Open "messages.php" in both folder and insert the following codes.

"messages.php" in 'en' folder.


return [
    'welcome'       => 'Welcome to our application'
];
Enter fullscreen mode Exit fullscreen mode

"messages.php" in 'fr' folder.


return [
    'welcome'       => 'Bienvenue sur notre application'
];
Enter fullscreen mode Exit fullscreen mode

Most important...

Add the below codes in "project_name/app/Http/Kernel.php" in "protected $middlewareGroups section".

\App\Http\Middleware\Localization::class,
Enter fullscreen mode Exit fullscreen mode

So your codes should be like this :

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',
        ],
    ];
Enter fullscreen mode Exit fullscreen mode

Now all this code in the route, "project_name/routes/web.php" on top of other defined routes.

Route::get('locale/{locale}', function ($locale){
    Session::put('locale', $locale);
    return redirect()->back();
});
Enter fullscreen mode Exit fullscreen mode

So in order to know the language that is being use, you can simply use :


<html lang="{{ app()->getLocale() }}">
Enter fullscreen mode Exit fullscreen mode

Changing language en/fr

To change the language, just create an anchor tag in html like the following :


<li><a href="{{ url('locale/en') }}" ><i class="fa fa-language"></i> EN</a></li>

<li><a href="{{ url('locale/fr') }}" ><i class="fa fa-language"></i> FR</a></li>

Enter fullscreen mode Exit fullscreen mode

To call the desired text :


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

Enter fullscreen mode Exit fullscreen mode

Top comments (23)

Collapse
 
chonz0 profile image
chonz0 •

TL;DR: how to fix a potential "too many redirects" error calling redirect()->back()

Nice article, thanks! Although, if you enter the locale URL directly on the browser URL bar, you could get a "too many redirects" error.
The underlaying problem is, in that particular case, you don't have a "back" URL (as the current URL is the first in the history stack, so Laravel returns the current URL when you call redirect()->back())
You can see it yourself by adding the following:

Route::get('locale/{locale}', function ($locale){
    dump(request()->fullUrl());
    dd(redirect()->back()->getTargetUrl());
});
Enter fullscreen mode Exit fullscreen mode

A quick fix would be to only call the back() method, if the target URL is different than the current one. You could achieve this by using the following snippet:

Route::get('locale/{locale}', function ($locale){
    Session::put('locale', $locale);

    if (request()->fullUrl() === redirect()->back()->getTargetUrl()) {
        return redirect('/');
    }

    return redirect()->back();
});
Enter fullscreen mode Exit fullscreen mode

Cheers!

Collapse
 
inshasamad18 profile image
inshasamad18 •

when i run this code i got an error page not found. the url should be like this 127.0.0.1:8000/localisation/create but when i change the language the url become 127.0.0.1:8000/localisation/lang/en.

Collapse
 
__mfarag profile image
Mina Farag •

thanks so much for this great description. i really appreciated it works for me just super fine.

Collapse
 
fadilxcoder profile image
fadilxcoder •

Thank you for your support :)

Collapse
 
fillipefelix profile image
fillipe-felix • • Edited

how can i add language to url
example example.com/pt-BR/content or example.com/en/content

Collapse
 
musthafaadvance profile image
musthafa-advance •

hey @filippe-felix did you solved this ?

Collapse
 
fillipefelix profile image
fillipe-felix •

Hi, no =(

Thread Thread
 
musthafaadvance profile image
musthafa-advance •
Thread Thread
 
musthafaadvance profile image
musthafa-advance • • Edited

youtube.com/watch?v=KqzGKg8IxE4

this will do it :)
Finally its fixed

Collapse
 
berangernelson profile image
Beranger nelson •

Comment faire pour les articles qui viennent de la base de donnée, pour qu'ils soient rendu en français et anglais svp ?.

Collapse
 
fadilxcoder profile image
fadilxcoder •

One way to do so is for example if you have a "posts" table with column : "id, title_en, title_fr, content_en, content_fr *" you can use if/else statement together with "app()->getLocale()*".

if(app()->getLocale() == 'en'):
    echo $var->title_en
else:
    echo $var->title_fr
endif;
Collapse
 
rezaodb profile image
Reza • • Edited

Or:

@if (app()->isLocale('en'))
  //
@endif
Enter fullscreen mode Exit fullscreen mode

But best method is to set a custom If Statement!

1: Add in your AppServiceProvider:

use Illuminate\Support\ServiceProvider;

public function boot()
{   
    Blade::if('lang', function ($language) {
        return app()->isLocale($language);
    });
}
Enter fullscreen mode Exit fullscreen mode

2: In your views:

@lang('en')
//

@elselang('fr')
//

@else
//

@endlang

Collapse
 
yara140305 profile image
Yaraa •

thank u so much

Collapse
 
fadilxcoder profile image
fadilxcoder •

Yes , I agree with you, if possible try to explain how to proceed so we all can know. Thank you.

Collapse
 
kodmanyagha profile image
Emir Buğra KÖKSALAN •

This is exaclty what I want. Other sites aren't making good explanation about this. Thanks.

Collapse
 
rezaodb profile image
Reza •

Hey, could somebody explain how to fix that? Thanks!!!

Collapse
 
mehdiyaq profile image
Mehdi Yaghoubi •

thank you.

does a with href attr work? as :

Collapse
 
ghersabilell profile image
Bilell Ghersa •

Hello, this is good for SEO ??