Why Your Middleware Isn't Getting Route Parameters (And How to Fix It)
Laravel 11>
If you've ever added middleware in your bootstrap/app.php file and found that it doesn't receive route parameters like project_id, you're not alone. Let's walk through why that happens—and how to fix it.
The Problem
Say you’ve created a middleware called SetCurrentProject that grabs the project_id from the route and uses it to set the current project in your app context.
Your routes might look like this:
Route::middleware(['web'])->group(function () {
Route::get('/project/{project_id}', [ProjectController::class, 'show']);
});
You add your middleware globally in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->append([
SetCurrentProject::class,
]);
})
You test the route... and your middleware doesn’t see any project_id. It’s like it doesn’t even exist.
The Reason
Global middleware runs before Laravel has matched the incoming request to a route. At that point, there’s no project_id because Laravel hasn’t yet figured out what route is being accessed.
So your SetCurrentProject middleware is running too early.
The Fix
Instead of appending globally, you want your middleware to run after the route is matched. That means adding it to the appropriate middleware group—typically web or api.
Here’s the updated bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('web', [
SetCurrentProject::class,
]);
})
Now SetCurrentProject will run after Laravel resolves the route, and the project_id will be available via:
$request->route('project_id');
Bonus Tip
If your middleware is only needed for a specific route or controller, you can always assign it directly in your routes file:
Route::get('/project/{project_id}', [ProjectController::class, 'show'])
->middleware(['web', SetCurrentProject::class]);
TL;DR: If your middleware needs route parameters, don’t register it globally. Add it to the web or api group—or directly to the route itself.