Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

IvanPujianto's avatar

How to execute middleware code first before router ?

Hi Guys, i have question about the order execution between middleware and route. which one will be executed first. for example, i have dd('hello from middleware') and i also put dd('hello from router'), which one i will see on browser ?

example code :

Middleware :

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\View;

class EntryPointMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        dd('hello from the middleware');

        return $next($request);
    }
}

and code from routes\web.php

use Illuminate\Support\Facades\Route;
use App\Http\Middleware\EntryPointMiddleware;

Route::middleware([EntryPointMiddleware::class])->group(function() {
    dd('hello from the route');
});

and is it possible if i want the script inside middleware to be executed first instead of router ? and how to do that ?

Thank you.

0 likes
7 replies
LaryAI's avatar
Level 58

In Laravel, middleware is designed to be executed before the route logic. This means that when you have both dd('hello from the middleware') in your middleware and dd('hello from the route') in your route, the middleware will be executed first. Therefore, you will see "hello from the middleware" in your browser.

Here's a breakdown of how it works:

  1. Middleware Execution: When a request is made, Laravel first checks if there are any middleware associated with the route. If there are, it executes the middleware in the order they are defined.

  2. Route Execution: After all middleware have been executed, Laravel then proceeds to execute the route logic.

In your example, since you have a dd('hello from the middleware') in your middleware, the execution will stop there, and you will see "hello from the middleware" in your browser. The dd('hello from the route') in your route will not be executed because dd() (dump and die) halts the execution.

If you want to ensure that the middleware is executed first, you don't need to do anything special because that's the default behavior. Just make sure your middleware is correctly applied to the route.

Here's a simplified explanation of your code:

// Middleware
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EntryPointMiddleware
{
    public function handle(Request $request, Closure $next): Response
    {
        dd('hello from the middleware'); // This will execute first and stop further execution.

        return $next($request);
    }
}

// Route
use Illuminate\Support\Facades\Route;
use App\Http\Middleware\EntryPointMiddleware;

Route::middleware([EntryPointMiddleware::class])->group(function() {
    dd('hello from the route'); // This will not be reached if the middleware has a dd().
});

In summary, middleware is always executed before the route logic, and if you use dd() in the middleware, it will prevent the route logic from executing.

IvanPujianto's avatar

@LaryAI yes, but what i got is "hello from the router", which mean, router is executed first ... so, why is that happening then ?

martinbean's avatar

@ivanpujianto Why not just explain what the actual problem you’re trying to solve is?

Why do you need to know which is executed first? What is it you’re actually trying to do before the router has ran?

IvanPujianto's avatar

@martinbean, thank you for ur suggestion.

Im implementing language switcher using form that made on the fly using JS when user click the btn language option as follow :

$('.btn-change-language').on('click', function(e){
		e.preventDefault();
		$('<form action="#" method="post">
				<input type="hidden" name="set_new_language" value="' + $(this).data('lang') + '"/>
				<input type="hidden" name="_token" value="{{ csrf_token() }}">
			</form>').appendTo('body').submit();
});

and then on EntryPointMiddleware, i try to detect the form submit and the language switching, and if the form submitted, i just change the language (set the session, etc) and call redirect()->back().

this is works for routes that using post, but for some routes, its not works, because they are using another method, for example get.

let say, my routes is this :

Route::middleware([EntryPointMiddleware::class])->group(function() {
	Route::get('/administrator', [AdministratorController::class, 'index'])->name('Administrator.index');
	Route::get('/administrator/{id}/edit', [AdministratorController::class, 'edit'])->name('Administrator.edit');

	Route::post('/administrator', [AdministratorController::class, 'store'])->name('Administrator.store');
});

on administrator.index, i can switch the language (but its using the wrong routes, its use Administrator.store instead of Administrator.index) and on edit page, when i switch the language, i got error that routes is not exists.

Meanwhile, i read on many articles, that middleware will be executed first, but its not the case when i try using dd() in both middleware and routes.

so, what is the correct execution order here ?

Thank you.

martinbean's avatar
Level 80

@IvanPujianto I don’t really understand what this has to do with routing or execution order to be honest.

If you want a user to be able to set their preferred language, then create a controller to handle requests for just that:

class PreferredLanguageController extends Controller
{
    public function store(StorePreferredLanguageRequest $request)
    {
        $request->session()->put('preferred_language', $locale = $request->input('language'));

        $message = __('Preferred language updated.', locale: $locale);

        return match ($request->expectsJson()) {
            true => response()->json(compact('message')),
            false => back()->with('success', $message),
        };
    }
}

You can then have a middleware that reads this session value, and sets the application locale for that request:

class SetPreferredLanguage
{
    public function handle(Request $request, Closure $next)
    {
        if ($locale = $request->session()->get('preferred_language')) {
            App::setLocale($locale);
        }

        return $next($request);
    }
}

Alternatively, you could set the preferred language on the authenticated user if you want a user to be able to pick their preferred language, and have that persist across log-ins:

class SetPreferredLanguage
{
    public function handle(Request $request, Closure $next)
    {
        if ($user = $request->user()) {
            App::setLocale($user->preferred_language ?? config('app.locale'));
        }

        return $next($request);
    }
}
1 like
IvanPujianto's avatar

@martinbean, Thank u so much for ur answer,

actually, initially i plan to handle request for switching language using middleware, but i think ur idea is much better, because i can save the new lang on user table in DB as preferred lang so i can use this the next time this user login. so, i will use ur idea, Thank you so much.

1 like

Please or to participate in this conversation.