DEV Community

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

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

fadilxcoder
Web Architect && Mobile App Developer - 🎮 💻 🎧 ☕
・2 min read

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

Discussion (24)

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 Author

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
fadilxcoder profile image
fadilxcoder Author

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

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 Author

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
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
xudush profile image
XuDuSh

thank you very much

Collapse
porngpiseyc profile image
Porngpisey Choem

If you could share about dynamic multi-language from MySQL, it really appriciate.

Thanks!

Collapse
syntafin profile image
Syntafin

I tried this and now I got the error as seen in the added screenshot

Collapse
mehdiyaq profile image
Mehdi Yaghoubi

thank you.

does a with href attr work? as :

Collapse
rezaodb profile image
Reza

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

Collapse
ghersabilell profile image
Bilell Ghersa

Hello, this is good for SEO ??

Collapse
julykrchnk profile image
july-krchnk

Does it also suitable for Laravel 6? Did someone try to do it?

Collapse
mahbod profile image
Mahbod Ahmadi

yeah i tried with laravel 7 :P