Multi-Language Routes and Locales with Auth

Multilanguage projects are quite easy to configure in Laravel, but if you want to have locale as part of URL, like /en/about, then you will have trouble with Auth::routes(), they won’t work by default like /en/register. This article will show you what to do.

If you prefer to watch video tutorials, here’s the video live-coding version of this article.

Step 1. Project Preparation.

First, we generate a default Laravel 5.7 project with laravel new laravel, and then run these commands:

php artisan make:auth
php artisan migrate

So, we have default Auth views in resources/views/auth, and also changed main resources/views/layouts/app.blade.php with Login/Register links.

Step 2. Route::group() for Locales

Next, we will add Route::group() for all possible URLs – so all the pages inside of the project will have prefix of /[locale]/[whatever_page]. Here’s how it looks in routes/web.php:

Route::group(['prefix' => '{locale}'], function() {

    Route::get('/', function () {
        return view('welcome');


    Route::get('/home', 'HomeController@index')->name('home');

All the routes above were pre-generated, we just moved them inside of our Route::group().

This group will cover such URLs like /en/ or /en/home or /en/register.

Now, for validation purposes let’s set {locale} to be only two letters, like en or fr or de. We add a regular-expression based rule inside of the group:

  'prefix' => '{locale}', 
  'where' => ['locale' => '[a-zA-Z]{2}']
], function() { // ...

Step 3. Setting App Locale with Middleware

People often think that Middleware classes are about restricting some access. But you can do more actions inside these classes. In our example, we will set app()->setLocale().

php artisan make:middleware SetLocale

This command will generate app/Http/Middleware/SetLocale.php, where we need to add only one line of code:

class SetLocale
    public function handle($request, Closure $next)
        return $next($request);

Variable $request->segment(1) will contain our {locale} part of the URL, so we set the app locale on all requests.

Of course, we need to register this class in app/Http/Kernel.php to the $routeMiddleware array:

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    // ...
    'setlocale' => \App\Http\Middleware\SetLocale::class,

Finally, we will apply this middleware to the whole locale group we created above:

  'prefix' => '{locale}', 
  'where' => ['locale' => '[a-zA-Z]{2}'], 
  'middleware' => 'setlocale'], function() { // ...

Step 4. Automated Redirect of Homepage

We need to add another line to routes/web.php – to redirect the user from non-localed homepage to /en/ homepage. This route will be outside of the Route::group() we created above:

Route::get('/', function () {
    return redirect(app()->getLocale());

This will redirect user from to, which will show default Welcome page.

Step 5. Add Locale Parameter to All Existing Links

Currently, if we click Login or Register link on top-right of our homepage, we will see an error like this:

The problem is that all views generated by make:auth command don’t know about locale at all. But we have put Auth::routes() under locale route group, so now ALL URLs should follow that rule and have locale parameter.

So we need to edit all the views in resources/views/auth and change all route() calls to pass one more parameter of app()->getLocale(). For example, this is the change in resources/views/auth/register.blade.php:

Line 11 – Before:

<form method="POST" action="{{ route('register') }}">

Line 11 – After:

<form method="POST" action="{{ route('register', app()->getLocale()) }}">

Same for other views, like resources/views/layouts/app.blade.php – we add parameter to all login/register/logout routes:

    <li class="nav-item">
        <a class="nav-link" href="{{ route('login', app()->getLocale()) }}">{{ __('Login') }}</a>
    @if (Route::has('register'))
        <li class="nav-item">
            <a class="nav-link" href="{{ route('register', app()->getLocale()) }}">{{ __('Register') }}</a>
    <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>
            {{ Auth::user()->name }} <span class="caret"></span>

        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
            <a class="dropdown-item" href="{{ route('logout', app()->getLocale()) }}"
                {{ __('Logout') }}

            <form id="logout-form" action="{{ route('logout', app()->getLocale()) }}" method="POST" style="display: none;">

Now, our register form will work under /en/register URL.

Step 6. Login and Register – Override $redirectTo with Locales

Next, if we do fill login or register form successfully, we will be redirected to /home URL – that’s a default Laravel setting. It won’t work in our case, because all URLs should have locale. So we need to add locale to the redirect URL.

To do that, we go to app/Http/Controllers/Auth/RegisterController.php and take a look at $redirectTo property:

class RegisterController extends Controller
    protected $redirectTo = '/home';

Not sure if you know, but you can override not only the property itself, but also create a method redirectTo() which would override the property value. It allows you to add any more complicated custom logic for redirection – for example, if you want to redirect different roles of users to different routes.

In our case, all we need to do is add a locale to the route:

public function redirectTo()
    return app()->getLocale() . '/home';

The same applies to app/Http/Controllers/Auth/LoginController.php, so we will copy-paste redirectTo() method there, too.

Now, after successful registration, you should land here:

Step 7. Choosing Language in TopBar

It’s pretty weird to have this visual step only now, but I wanted to get to “how it works” before showing “how it looks”.

Now, let’s implement a language choice in the header visually. Like this – see three languages on top:

It’s actually pretty simple, as we have all the system ready for it.

First, let’s define the array of possible languages, in config/app.php we will add an array of available_locales:

// ...

'locale' => 'en',

'available_locales' => [

Then, in the top section of resources/views/layouts/app.blade.php we add this @foreach loop:

<!-- Right Side Of Navbar -->
<ul class="navbar-nav ml-auto">
    @foreach (config('app.available_locales') as $locale)
        <li class="nav-item">
            <a class="nav-link"
               href="{{ route(\Illuminate\Support\Facades\Route::currentRouteName(), $locale) }}"
                @if (app()->getLocale() == $locale) style="font-weight: bold; text-decoration: underline" @endif>{{ strtoupper($locale) }}</a>

A few things to comment here:

  • We’re taking the list of languages from config(‘app.available_locales’) that we had just created above;
  • We’re giving the href link to the same current route but with a different language – for that we’re using Route::currentRouteName() method;
  • Also we’re checking for active current language with app()->getLocale() == $locale condition;
  • Finally, we’re showing the language itself in uppercase mode with strtoupper($locale).

Step 8. Filling in Translations

This is the goal we’ve been working for – so that /en/register URL would show form in English, and /de/register – in German language.

Let’s keep our en locale as default, and we need to fill in the translations for other languages.

If you look at resources/views/auth/login.blade.php file and other views, they all use underscore __() method to get the texts, see examples below:

<div class="card-header">{{ __('Login') }}</div>

<label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

<label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

<label class="form-check-label" for="remember">
    {{ __('Remember Me') }}

<button type="submit" class="btn btn-primary">
    {{ __('Login') }}

<a class="btn btn-link" href="{{ route('password.request', app()->getLocale()) }}">
    {{ __('Forgot Your Password?') }}

So, all we need to do is to fill in the files in other languages. Let’s create a file resources/lang/fr.json and fill in some translations:

  "Login": "Se connecter",
  "E-Mail Address": "E-mail",
  "Password": "Mot de passe",
  "Remember Me": "Se souvenir de moi",
  "Forgot Your Password?": "Mot de passe oublié?"

Notice: I’m not French, these translations are taken from one client project, don’t judge if translation is wrong 🙂

Final visual result, if we hit a Login link on a French language:

That’s it!

You can find full code repository for this project here on Github.

Like our articles?
Check out our Laravel online courses!


    • Hi Kevin, thanks for the comment. Didn’t reproduce that one, are you sure you added this in app.blade.php? {{ route(‘logout’, app()->getLocale()) }}

      • I have that in my app.blade.php, the error only happens when I am not logded in. When I go to localhost:8000, it redirects to localhost:8000/en and gives this error:
        “Missing required parameters for [Route: login] [URI: {locale}/login].”
        “PHP 7.2.3 Development Server”

        Here is my web route:
        Route::get(‘/’, function() {
        return redirect(app()->getLocale());

        Route::group([‘prefix’ => ‘{locale}’, ‘where’ => [‘locale’ => ‘[a-zA-Z]{2}’], ‘middleware’ => ‘setLocale’], function() {
        //Group Auth Routes
        Route::middleware(‘auth’)->group( function () {
        Route::get(‘/’, ‘HomeController@index’)->name(‘home’);
        Route::get(‘/home’, ‘HomeController@index’)->name(‘home’);
        Route::get(‘/kwords’, array(‘as’ => ‘kwords’, ‘uses’=>’ProposalController@getKeywords’));

        Route::middleware(‘auth’)->group( function () {
        Route::get(‘/get-collabs/{pid}’, ‘CollaboratorController@getCollabs’)->name(‘get-collabs’);
        Route::middleware(‘admin’)->group( function () {

        • Could you debug the error further and see in which file exactly it’s missing locale? Info should be in storage/logs/laravel.log.

          • Here it is in the log:
            [2019-02-18 15:16:23] local.ERROR: Missing required parameters for [Route: login] [URI: {locale}/login]. {“exception”:”[object] (Illuminate\\Routing\\Exceptions\\UrlGenerationException(code: 0): Missing required parameters for [Route: login] [URI: {locale}/login]. at E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Exceptions\\UrlGenerationException.php:17)
            #0 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteUrlGenerator.php(90): Illuminate\\Routing\\Exceptions\\UrlGenerationException::forMissingParameters(Object(Illuminate\\Routing\\Route))
            #1 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\UrlGenerator.php(388): Illuminate\\Routing\\RouteUrlGenerator->to(Object(Illuminate\\Routing\\Route), Array, true)
            #2 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\UrlGenerator.php(369): Illuminate\\Routing\\UrlGenerator->toRoute(Object(Illuminate\\Routing\\Route), Array, true)
            #3 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\helpers.php(812): Illuminate\\Routing\\UrlGenerator->route(‘login’, Array, true)
            #4 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php(220): route(‘login’)
            #5 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Exceptions\\Handler.php(180): Illuminate\\Foundation\\Exceptions\\Handler->unauthenticated(Object(Illuminate\\Http\\Request), Object(Illuminate\\Auth\\AuthenticationException))
            #6 E:\\xampp\\htdocs\\funding_app\\app\\Exceptions\\Handler.php(49): Illuminate\\Foundation\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(Illuminate\\Auth\\AuthenticationException))
            #7 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(83): App\\Exceptions\\Handler->render(Object(Illuminate\\Http\\Request), Object(Illuminate\\Auth\\AuthenticationException))
            #8 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(55): Illuminate\\Routing\\Pipeline->handleException(Object(Illuminate\\Http\\Request), Object(Illuminate\\Auth\\AuthenticationException))
            #9 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken.php(68): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #10 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #11 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #12 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\View\\Middleware\\ShareErrorsFromSession.php(49): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #13 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #14 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #15 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Session\\Middleware\\StartSession.php(63): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #16 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Session\\Middleware\\StartSession->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #17 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #18 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse.php(37): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #19 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #20 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #21 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Cookie\\Middleware\\EncryptCookies.php(66): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #22 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #23 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #24 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #25 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(667): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
            #26 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(642): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
            #27 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(608): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
            #28 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php(597): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
            #29 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(176): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
            #30 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(30): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
            #31 E:\\xampp\\htdocs\\funding_app\\vendor\\fideloper\\proxy\\src\\TrustProxies.php(57): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #32 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Fideloper\\Proxy\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #33 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #34 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(31): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #35 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #36 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #37 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php(31): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #38 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #39 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #40 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php(27): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #41 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #42 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #43 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode.php(62): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #44 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(151): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Illuminate\\Http\\Request), Object(Closure))
            #45 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
            #46 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php(104): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
            #47 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
            #48 E:\\xampp\\htdocs\\funding_app\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
            #49 E:\\xampp\\htdocs\\funding_app\\public\\index.php(55): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
            #50 E:\\xampp\\htdocs\\funding_app\\server.php(21): require_once(‘E:\\\\xampp\\\\htdocs…’)
            #51 {main}

          • Ok could you search through all project (like in PHPStorm there’s right-click -> “Find in Path”) for “route(‘login’)”? I guess it can be somewhere in core middlewares of Laravel vendor.

          • I found the culprit. The route(‘login’) is in the protected function unauthenticated($request, AuthenticationException $exception) located at E:\xampp\htdocs\funding_app\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php

  1. Hi great article. thanks . But some problems happened. i cannot get when i try => error happen too… is working but blog posts with slug and pages with slug is not working how to fix ?

    Route::get(‘/’, function () {
    return redirect(app()->getLocale());

    ‘prefix’ => ‘{locale}’,
    ‘where’ => [‘locale’ => ‘[a-zA-Z]{2}’],
    ‘middleware’ => ‘setlocale’
    ], function() {

    Route::get(‘page/{slug}’, function($slug){
    $page = App\Page::where(‘slug’, ‘=’, $slug)->firstOrFail();
    $pages = App\Page::where(‘status’,’ACTIVE’)->get();
    return view(‘page’, compact(‘page’,’pages’));


  2. Hey Povilas, hope you are well.
    Thank you for this guide, I was wondering to know how did you manage to make the password reset work.

    I am kinda stuck here, I got two issues, I hope you can help with that.

    1. On the reset.blade.php view, the request returns the locale “en” instead of the password reset token value.
    2. In the email body the link structure is incorrect.

    If I dd($request->all()) on the ResetPasswordController@reset method this is what I get:

    array:5 [▼
    “_token” => “YrwPp06e6dV3iVlyQ59y1lvcNvOwCoQr0bIyAwgX”
    “token” => “en”
    “email” => “”
    “password” => “password”
    “password_confirmation” => “password”
    the input on the reset.blade.php template looks like this:

    But when I inspect it with chrome dev tools it’s like so:

    The structure of the reset link inside the email body is formatted like so: localhost/long_token_string_here/password/reset, instead of localhost:8000/en/password/reset/long_token_string_here

    This are my routes
    ‘prefix’ => ‘{locale}’,
    ‘where’ => [‘locale’ => ‘[a-zA-Z]{2}’],
    ‘middleware’ => ‘setLocale’
    function () {
    Route::get(‘/password/email/’, ‘Auth\ForgotPasswordController@showLinkRequestForm’)->name(‘’);
    Route::post(‘/password/email/’, ‘Auth\ForgotPasswordController@sendResetLinkEmail’)->name(‘’);

    Route::get(‘/password/reset/{token}’, ‘Auth\ResetPasswordController@showResetForm’)->name(‘password.reset’);
    Route::post(‘/password/reset/’, ‘Auth\ResetPasswordController@reset’)->name(‘password.reset’);


    • Hi Fabio,
      Unfortunately I don’t have a quick answer for you, nothing obvious here, would need to debug your code with full project and then maybe would find something. But I don’t have such “service” as debugging errors for someone.

    • Hi, i was having the same issue in laravel 6, this is what i did, i set the locale parameter as a default value so i dont have to set it on every link. You can do this in your middleware:

      URL::defaults([‘locale’ => $request->segment(1)]);
      return $next($request);

      • namespace App\Http\Middleware;

        use Closure;
        use Illuminate\Support\Facades\URL;

        class Locale
        * Handle an incoming request.
        * @param \Illuminate\Http\Request $request
        * @param \Closure $next
        * @return mixed
        public function handle($request, Closure $next)
        URL::defaults([‘locale’ => $request->segment(1)]);
        return $next($request);

  3. Hello Povilas,

    Thank you very much for this great tutorial!

    Have a question related to: Step 4. Automated Redirect of Homepage
    When I go to non-localed homepage, (e.g. laravel.test), I am getting the following error message:

    ErrorException (E_RECOVERABLE_ERROR)
    Object of class Illuminate\Routing\Redirector could not be converted to string

    Trying to find the reason for this, but without success.
    Could you please help?

    Thank you very much and best regards,

    • Hi Bratislav,
      Sorry, I haven’t seen that error before, so not sure what you did wrong, I can’t debug it for you remotely.

      There is a possibility that I did something wrong, too (or Laravel updated something), but so far other users didn’t complain about this part.

  4. Hey Povilas, really cool tutorial!
    I would like to ask you about your language switcher with possible parameters in routes?
    When I using some route like ” {locale}/company/{id}/edit “, languages switcher lost second parameter {id} from url address.
    How is possible to solve this? How to let switcher know about other few parameters?

    • Good question Oleg. My article covered the basic idea, but for deeper examples like yours you need to adapt it yourself, I guess. Probably extend the language switcher to accept more parameters? Not sure, unfortunately it won’t be a one-line answer.

    • @oleg: you can pass array as second parameter like this:
      route(‘company.edit’, [‘id’ => $company->id, ‘locale’ => app()->getLocale()]

    • My previous comment got removed the html to it, I’ll be more clear. Just change the current href code inside the foreach loop of your language switcher for this:

      route(\Illuminate\Support\Facades\Route::currentRouteName(),array_merge(Route::current()->parameters(),[‘locale’=> $locale]))

      • Everything works perfectly ok with the configuration…except for the route to / and logout….
        the error says: Route[] not defined
        when the route is clearly defined…. I must be missing something….
        Any ideas what might be gone wrong?

        • Great guide. Thanks @Povilas.

          Hi @gagboi717.
          I had the “Route[] not defined” error too in Laravel 6.0. Adding “->name(‘routename’)” to my route fixed it. Could be a bug.

          Route::get(‘/myroute’, ‘MyController@index’); // not working

          Route::get(‘/myroute’, ‘MyController@index’)->name(‘myroute’); // works

  5. Hello Povilas,

    Here I am again.
    I have managed to make my application work properly, based on the inputs from your tutorial.

    Have additional question, again related to: Step 4. Automated Redirect of Homepage.

    When I go to non-localed homepage, (e.g. laravel.test), I would like to be:
    1. redirected to /en/ homepage (default locale), when visiting site for the first time, or
    2. redirected to the language, I chose during the previous site visit.

    I understand that there should be some playing with the locale value saved in session.
    If you have anything to be shared, related to this approach, I will be very thankful.

    Thank you very much and best regards,

  6. Check out setting the ‘locale’ variable in all route(‘some route’) calls automatically with Url::defaults([‘locale’ => $locale]) in the middleware, probably. This fixes the route calls – not sure about url calls – those would have to be changed to route

  7. Hi I want to set language in my website on home page and wherever but when i write app()->setLocale() in route it give me an Error of route not definied
    Please give me a FeedBack Thank you !

    • I had the same problem. but i found a way to fix it.

      You are getting null message because your controller i recieving the locale inthead of the id you are sending to it. so to fix that you route have to be like this:
      Example: {{ route(‘user.edit’,[app()->getLocale(), $user->id]) }}

      So now if you make dd($id) you will get the locale value, don’t worry. What you have to do in you controller is to store the segment of the url that contain your id into a variable like that:
      $user-id = request()->segments(2);
      //Note: Check in what position of the array you are receiving the id, in my case i got it on position #2

      and the you can do your consult: $edit = Category::find($user-id);

      Hope can help you.
      I had several days looking for this post to make my contribution

  8. Hello,

    I have issue with 404 error pages.
    I have had to customise quite a few lines my own but the issue is that 404 pages give “Call to a member function parameters() on null” error. Anyone have any idea how to fix this issue??

  9. Invalid argument supplied for foreach() (View: C:\xampp\htdocs\moon technolabs\work home\Green_cup\resources\views\layouts\app.blade.php)

  10. need one more step… modify “logout” action

    in app\http\controllers\auth\LoginController add next rows

    use Illuminate\Http\Request;

    public function logout(Request $request)



    if ($response = $this->loggedOut($request)) {
    return $response;

    return $request->wantsJson()
    ? new Response(”, 204)
    : redirect($this->redirectTo());

  11. Very nice tutorial !!
    What do you think about defining available locales in config app.locales as on array, then, your route group constraint whould like this:
    ‘where’ => [‘locale’ => ‘^’. implode(‘|’, config(‘app.locales’)) .’$’]

  12. how can we give route on {locale}/edit/{id}. i can give only {locale} value through
    getLocale()}}” data-toggle=”modal” data-target=”#confirm-delete”>

    this code

  13. Thank you for this article but there’s a problem I’m facing, the problem with that is after creating this global prefix I need to pass the locale to every method in the controller which I really don’t need ! is there a way to pass a global variable to every controller method or something ?

    • Ok I fixed that.
      if anyone looking for this, in the middleware append default parameter *to avoid using the locale in every request as in route(‘register’, app()->getLocale()), you can use the old one route(‘register’)*
      Url::defaults([‘locale’ => $request->segment(1)]);
      another thing you may face that when you use your resource controller it will ask for the locale in every method that has parameter and it will look for the locale as the first parameter
      to avoid that remove the local from the request

  14. Hello Sir, I implemented all your instructions everything goes right but I’ve only one issue about reset password link. Please help me with this situation!

    Missing required parameters for [Route: password.reset] [URI: {locale}/password/reset/{token}].

  15. I need some modifications ideas that are essential in this case. first, it works every two letter string while i need it for only available_locales array otherwise 404. second, how to route different pages of locales in route group. something like ‘{locale}.home’ as a route parameter for my blade template. How to implement this.

  16. Hello, Thanks for the tutorial.

    I need some help, after i make my web multi-lang following your tutorial, i get the follow error, i’m making a CRUD but when i send parameters to edit route, i get a message “Missing required parameters for [Route: clientes.edit]”

    i doing that way on the edit button: {{ route(‘clientes.edit’, $cliente->id, app()->getLocale()) }}

  17. Hi,
    I have implemented this way in my code and its working but the problem is that I have to add $locale argument in every controller like
    public function show($locale, $id, $slug){}
    here, if I don’t put this $local argument in my controller $id will take the $locale value.
    Do you have any implementation for this.
    Please let me know

    • I solved this problem by using one of the answers provided above. setting

  18. Thanks for this article it’s very helpful, one issue though when I log out using fr for example, it returned back to the default language. how can we stay to the current language when you log out, thanks in advance.

  19. This is quite good article regarding localization. If you follow this tutorial you will get stuck with password reset because when you use Laravel’s build-in email send for password reset, there is no ‘locale’ param sent, so it will blow up. You have to dig really deep to understand what’s going on, so if you get stuck you will have to create your own Notification for sending email. It’s little bit of work but it’s only way to do it if you wan’t this approach. These article explains how you can achieve this, so check it out

  20. Thanks for this article. It helped a lot. I only have one issue: to localize my pages I’ve used trans(‘route.label’) in my route-patterns. But for some reason those always revert to the default language.
    I got for instance a members page which has a route “/_trans(‘routes.profile’)” which generates ‘/en/profile’ and ‘/nl/profiel’.

    When I go to https://mysite/nl/profiel the urls generated on that page via route() (in the menu etc) still use the EN-labels, not the NL labels. Somehow the route()-function doesn’t pick up the language I set in the middleware (& yes: in /lang/nl/routes.php I entered the translated strings ;o)

    How can this be resolved?

    A more elaborate description with code snipptes of my issue is available here:

  21. Hi everyone.. I working on a website with two language to show success stories .. the problem start when click read More I get an issue when I pass the param of slug to the route, this is my route in balde :

    {{ route(‘exercise’,[‘slug’ => $article->slug,’locale’ => App()->getLocale()]) }}

  22. I like your approach but there is a problem when your are not logged in and try to access an “auth protected” route. You will see an error complaining about missing locale.

    In this case you may override the unauthenticated method from Illuminate\Foundation\Exceptions\Handler in your App\Exceptions\Handler:

    * Convert an authentication exception into a response.
    * @param \Illuminate\Http\Request $request
    * @param \Illuminate\Auth\AuthenticationException $exception
    * @return \Symfony\Component\HttpFoundation\Response
    protected function unauthenticated($request, AuthenticationException $exception)
    return $request->expectsJson()
    ? response()->json([‘message’ => $exception->getMessage()], 401)
    : redirect()->guest($exception->redirectTo() ?? route(‘login’));

  23. solution of this problem [Route: login] [URI: {locale}/login]
    go to middleware folder and open authenticated folder and replace this function
    protected function redirectTo($request)
    if (! $request->expectsJson()) {
    return route(‘login’, [‘locale’ => app()->getLocale()]);


  24. Hi, when a click on FR language button, only prefix change (fr/login), how can i do to change route and prefix according language?



  25. Hi,

    Very good tutorial, one thing I would like to in addition like default local should not include in URL, please guide me

    for eg.
    localhost/home (Default locale: en)

  26. excellent tutorial very useful for me, it was very difficult for me to change all the routes in the blade sheet, so in setLocale() I added a session(‘lang’) without using segment (1) …without changing routes


Please enter your comment!
Please enter your name here