Dependency Injection
Laravel allows you to automatically inject dependencies into route callbacks.
For example, if you type-hint the Request class, Laravel will pass the current HTTP request automatically:
use Illuminate\Http\Request;
Route::get('/users', function (Request $request) {
return $request->all(); // Access query or form data
});
CSRF Protection
When creating forms for POST, PUT, PATCH, or DELETE routes, you must include a CSRF token to prevent malicious attacks.
<form method="POST" action="/profile">
@csrf
<button type="submit">Update</button>
</form>
If the token is missing, Laravel will reject the request.
Redirect Routes
Instead of writing a full controller for simple redirects, use Route::redirect:
Route::redirect('/here', '/there'); // 302 Redirect
Route::redirect('/here', '/there', 301); // Custom status
Route::permanentRedirect('/here', '/there'); // Shortcut for 301
View Routes
If a route only returns a view, you can simplify with Route::view:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
Listing Routes
Use Artisan to see all registered routes:
php artisan route:list
php artisan route:list -v # Show middleware
php artisan route:list -vv # Expand middleware groups
php artisan route:list --path=api # Filter by prefix
php artisan route:list --except-vendor # Hide package routes
php artisan route:list --only-vendor # Show only package routes
Routing Customization
By default, routes are loaded from routes/web.php and routes/api.php, but you can customize this in bootstrap/app.php.
Add extra route file:
->withRouting(
web: __DIR__.'/../routes/web.php',
then: function () {
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
},
)
i) withRouting
This is part of Laravel’s Application bootstrap process (introduced in Laravel 11+).
Instead of the old way ($app->router->group(...) in routes/web.php or RouteServiceProvider), Laravel now provides ->withRouting() when bootstrapping the app in bootstrap/app.php.
It lets you declare which route files to load, and optionally pass a closure (then) to define extra route groups.
ii) web: __DIR__.'/../routes/web.php'
Here, the app is being told:
👉 Load the normal web routes from routes/web.php.
This is equivalent to how Laravel used to load them by default.
iii) then: function () { ... }
The then callback runs after the default route files are registered.
Inside it, you can register additional route groups.
iv) Inside the closure
Route::middleware('api')
->prefix('webhooks')
->name('webhooks.')
->group(base_path('routes/webhooks.php'));
middleware('api')→ Every route inside will automatically use the API middleware group (things like rate limiting, JSON response formatting, etc.).prefix('webhooks')→ All routes inside will be prefixed with/webhooks/....name('webhooks.')→ All route names inside will be prefixed withwebhooks.(e.g.,webhooks.payment,webhooks.github).group(base_path('routes/webhooks.php'))→ Loads routes fromroutes/webhooks.php.
So if routes/webhooks.php contains:
Route::post('/payment', [WebhookController::class, 'payment'])->name('payment');
The actual route will be:
- URL:
/webhooks/payment - Name:
webhooks.payment - Middleware:
api
This snippet loads your regular web.php routes, and then also loads a dedicated group of webhook routes from routes/webhooks.php, all under /webhooks/*, using API middleware, and with webhooks. as the name prefix.
Full control (manual registration):
->withRouting(
using: function () {
Route::middleware('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
},
)
