Mastering Laravel Routing – Part 3

aravel Laravel Views & Blade Templates – Beginner’s Guide

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 with webhooks. (e.g., webhooks.payment, webhooks.github).
  • group(base_path('routes/webhooks.php')) → Loads routes from routes/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'));
    },
)