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');
});
Auth::routes();
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:
Route::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)
{
app()->setLocale($request->segment(1));
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:
Route::group([
'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 yourdomain.com to yourdomain.com/en, 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:
@guest
<li class="nav-item">
<a class="nav-link" href="{{ route('login', app()->getLocale()) }}">{{ __('Login') }}</a>
</li>
@if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register', app()->getLocale()) }}">{{ __('Register') }}</a>
</li>
@endif
@else
<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>
</a>
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout', app()->getLocale()) }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout', app()->getLocale()) }}" method="POST" style="display: none;">
@csrf
</form>
</div>
</li>
@endguest
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' => [
'en',
'de',
'fr'
],
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>
</li>
@endforeach
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') }}
</label>
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
<a class="btn btn-link" href="{{ route('password.request', app()->getLocale()) }}">
{{ __('Forgot Your Password?') }}
</a>
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.
Don’t worry, your french translations are good 🙂
Great and nice tutorial.
“Merci”
FYI, When you log out you get an error for the locale parameter.
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].”
DOCUMENT_ROOT
“E:\xampp\htdocs\funding_app\public”
REMOTE_ADDR
“127.0.0.1”
REMOTE_PORT
“53717”
SERVER_SOFTWARE
“PHP 7.2.3 Development Server”
SERVER_PROTOCOL
“HTTP/1.1”
SERVER_NAME
“127.0.0.1”
SERVER_PORT
“8000”
REQUEST_URI
“/en”
REQUEST_METHOD
“GET”
SCRIPT_NAME
“/index.php”
SCRIPT_FILENAME
“E:\xampp\htdocs\funding_app\public\index.php”
PATH_INFO
“/en”
PHP_SELF
“/index.php/en”
HTTP_HOST
“localhost:8000”
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() {
Auth::routes();
//Group Auth Routes
Route::middleware(‘auth’)->group( function () {
Route::get(‘/’, ‘HomeController@index’)->name(‘home’);
Route::get(‘/home’, ‘HomeController@index’)->name(‘home’);
//Proposal
Route::get(‘/proposal’,’ProposalController@index’)->name(‘proposal’);
Route::get(‘/proposal/create’,’ProposalController@create’);
Route::get(‘/kwords’, array(‘as’ => ‘kwords’, ‘uses’=>’ProposalController@getKeywords’));
Route::get(‘/proposal/{proposal}/edit’,’ProposalController@edit’)->name(‘proposal-edit’);
});
});
/*
|——————————————————————————————————
| LANGUAGE NOT NEEDED FOR THIS
|——————————————————————————————————
*/
Route::middleware(‘auth’)->group( function () {
//Proposal
Route::post(‘/proposal’,’ProposalController@store’);
Route::patch(‘/proposal/{proposal}’,’ProposalController@update’);
Route::delete(‘/proposal/{proposal}’,’ProposalController@destroy’);
//Collabs
Route::get(‘/get-collabs/{pid}’, ‘CollaboratorController@getCollabs’)->name(‘get-collabs’);
Route::resource(‘collaborator’,’CollaboratorController’);
});
/*
|——————————————————————————————————
| ADMIN SECTION ROUTES – NOT MULTI LANGUAGE
|——————————————————————————————————
|
*/
Route::middleware(‘admin’)->group( function () {
Route::get(‘admin’,’AdminController@index’)->name(‘admin’);
Route::get(‘/admin/researchers’,’ResearcherController@index’)->name(‘researchers’);
Route::get(‘/admin/{proposal}’,’AdminController@show’);
Route::delete(‘/admin/{proposal}’,’AdminController@destroy’);
});
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)
[stacktrace]
#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
Great article, all works nice!
Can I ask you, how to make it works with email verify ?
I get stuck when clicking on recived email link or trying to access url like:
http://127.0.0.1:8000/1553090303/email/verify/4?signature=b33f399969fe14bb98f7b27eaa83b73519166e3c4b36828893e4d96e5a5acb64
Thank you
in advance
(yes, working on local and mailtrap)
Hi Raül
To be honest, I didn’t try with email verification, so you would have to modify default functionality to achieve it, unfortunately don’t have a short answer for you.
Ok! thank you,
keep on coding 😉
customizing the function on VerifyEmail works ^^:
protected function verificationUrl($notifiable)
{
return URL::temporarySignedRoute(
‘verification.verify’,
Carbon::now()->addMinutes(Config::get(‘auth.verification.expire’, 60)),
[‘id’ => $notifiable->getKey(), ‘locale’ => app()->getLocale()]
);
}
Awesome!
Hi dear Ràul ,
Where did you do this?
Several actions must be performed to be able to use with email validation.
Thanks for sharing this Povilas!
Hi great article. thanks . But some problems happened. i cannot get example.com/post/example-slug when i try => example.com/en/post/example-slug error happen too… example.com/en/blog is working but blog posts with slug and pages with slug is not working how to fix ?
web.php
=====================================
Route::get(‘/’, function () {
return redirect(app()->getLocale());
});
Route::group([
‘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’));
});
});
==============================================
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” => “mail@admin.com”
“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
“`
Route::group(
[
‘prefix’ => ‘{locale}’,
‘where’ => [‘locale’ => ‘[a-zA-Z]{2}’],
‘middleware’ => ‘setLocale’
],
function () {
Route::get(‘/password/email/’, ‘Auth\ForgotPasswordController@showLinkRequestForm’)->name(‘password.email’);
Route::post(‘/password/email/’, ‘Auth\ForgotPasswordController@sendResetLinkEmail’)->name(‘password.email’);
Route::get(‘/password/reset/{token}’, ‘Auth\ResetPasswordController@showResetForm’)->name(‘password.reset’);
Route::post(‘/password/reset/’, ‘Auth\ResetPasswordController@reset’)->name(‘password.reset’);
});
“`
Thanks
Fabio
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:
setLocale($request->segment(1));
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)
{
app()->setLocale($request->segment(1));
URL::defaults([‘locale’ => $request->segment(1)]);
return $next($request);
}
}
Thank you very much, it was helpfull 🙂
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,
Bratislav
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.
Hi Povilas,
Thank you for the quick reply.
Will try to explore more on my own.
Best regards,
Bratislav
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.
Thank you, Povilas for your answer & good tutorial article!
@oleg: you can pass array as second parameter like this:
route(‘company.edit’, [‘id’ => $company->id, ‘locale’ => app()->getLocale()]
In the case of the language switcher, you can replace Povilas code for this one:
@foreach (config(‘app.all_langs’) as $locale)
parameters(),[‘locale’=> $locale])) }}”
@if (app()->getLocale() == $locale) style=”font-weight: bold; text-decoration: underline” @endif>{{ $locale }}
@endforeach
It will replace in the route the locale and leave the rest as it is in the current page.
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]))
you save my day thank you
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.
Before:
Route::get(‘/myroute’, ‘MyController@index’); // not working
After:
Route::get(‘/myroute’, ‘MyController@index’)->name(‘myroute’); // works
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,
Bratislav
Hi Bratislav,
Not sure what exactly you need help with, it’s pretty straightforward:
Route::get(‘/’, ‘HomepageController@redirect’);
And then inside of that redirect() method use some if-else logic and return redirect()->route(‘some_language_route’);
Hi Povilas,
Yes. You were right. It was straight forward.
Thank you very much.
Bratislav
Step 4:
Route::get(‘/’, function () {
if(\Session::has(‘locale’))
{
$language = session()->get(‘locale’);
return redirect($language);
} else {
return redirect(app()->getLocale());
}
});
Except that it’s apparently not a good idea – from an SEO perspective – to use a 302 redirect from mydomain.com to mydomain.com/en. See https://searchengineland.com/seo-when-your-domain-homepage-are-not-the-same-131592
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
Phillip Harrington thank you very much, it is little but very important note
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 !
Hi, I tried to edit the method, the url is correct (en/category/1/edit), but the data is null.
index.blade
id, ‘locale’=>app()->getLocale()], false) }}” class=”btn btn-success”>Edit
controller
$edit = Category::find($id);
dd($edit);
is there a solution ?
i have the same problem
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
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??
This doesn’t work for me with Laravel 6, if you are gonna try it make sure you commit before start.
Invalid argument supplied for foreach() (View: C:\xampp\htdocs\moon technolabs\work home\Green_cup\resources\views\layouts\app.blade.php)
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)
{
$this->guard()->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($response = $this->loggedOut($request)) {
return $response;
}
return $request->wantsJson()
? new Response(”, 204)
: redirect($this->redirectTo());
}
How can I add a picture with the country flag next to ‘EN’, ‘DE’ or ‘FR’
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’)) .’$’]
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
This doesn’t work for me with Laravel 6, if you are gonna try it make sure you commit before start.
in the header, if there are parameters in any route , you will get this error “Missing required parameters”
so, in order to get around that, I suggest changing the link to the following:
“`
parameters()), $locale)}}”
@if (app()->getLocale() == $locale) style=”font-weight: bold; text-decoration: underline” @endif>
{{ strtoupper($locale) }}
“`
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
$request->route()->forgetParameter(‘locale’);
Hi Mahmuod Ben Jabir, can you illustrate this $ request-> route () -> forgetParameter (‘locale’); ? I have the same thing as you.
thank you
thank you i succeeded.
Forget parameter solves the issue, i will no more need to add a new argument to all existing controllers, saves time
Hello Mahmuod Ben Jabir, can you tell in what class you put this Url::defaults([‘locale’ => $request->segment(1)]); ?
Ok, I do this, now I don’t know where to put $request->route()->forgetParameter(‘locale’); ? in every request ?
thank you this article was very helpful
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!
Illuminate\Routing\Exceptions\UrlGenerationException
Missing required parameters for [Route: password.reset] [URI: {locale}/password/reset/{token}].
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.
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()) }}
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
$request->route()->forgetParameter(‘locale’)
i have this:
public const HOME = ‘/home’;
how can i make it return this
HOME = app()->getLocale() . ‘/home’;
???
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.
After registered successful go back to the previous page in use Multi-Language Routes and Locales with Authin laravel
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
https://stackoverflow.com/questions/45104905/override-password-reset-url-in-email-template-laravel-5-3
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: https://stackoverflow.com/questions/65219477/laravel-8-route-does-not-localize-strings
I found the one package to solve all my route translation needs: https://github.com/codezero-be/laravel-localized-routes 🙂
it seems to be the better and that is what i want thank you!.
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()]) }}
I prefer setting default route parameter for locale. So there’s no need to pass locale to every route link.
From docs:
“Sometimes, you may wish to specify request-wide default values for URL parameters, such as the current locale. To accomplish this, you may use the URL::defaults method.”
https://laravel.com/docs/8.x/urls#default-values
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’));
}
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()]);
}
}
Hi, when a click on FR language button, only prefix change (fr/login), how can i do to change route and prefix according language?
fr/se-connecter
en/login
tks…
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)
localhost/ar/home
localhost/es/home
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