Skip to main content
Routing

Routing

Routes connect a URL and HTTP verb to code. They live in routes/web.php for browser requests and routes/api.php for stateless API endpoints. The web file applies session, cookie, and CSRF middleware; the API file does not.

Illustration of a request passing a router, a middleware shield, a controller, and a layered view
The router selects a route, middleware filters the request, and the controller returns a response.

Basic routes

use Illuminate\Support\Facades\Route;

Route::get('/', fn () => view('welcome'));
Route::post('/contact', [ContactController::class, 'store']);
Route::put('/posts/{post}', [PostController::class, 'update']);
Route::delete('/posts/{post}', [PostController::class, 'destroy']);

Route::match accepts several verbs, and Route::any accepts all of them. Prefer explicit verbs; they document intent and make caching and testing easier.

Route parameters

Parameters are passed to the route callback in order. Add a constraint to restrict what the parameter may contain.

Route::get('/posts/{post}', [PostController::class, 'show'])
    ->whereNumber('post');

Route::get('/archive/{year}/{month?}', function (string $year, ?string $month = null) {
    return "Archive for {$year} {$month}";
})->where(['year' => '[0-9]{4}', 'month' => '[0-9]{2}']);

Named routes

Names decouple URL generation from paths. Rename a path once and every route() call follows.

Route::get('/dashboard', DashboardController::class)
    ->name('dashboard');

// later
return redirect()->route('dashboard');

Groups

Groups share prefixes, middleware, names, and controllers across many routes. This keeps large route files readable.

Route::prefix('admin')->name('admin.')->middleware('auth')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('dashboard');
    Route::resource('posts', AdminPostController::class);
});

Implicit model binding

When a parameter name matches a type-hinted model, Laravel loads the record automatically or returns a 404. Custom keys can be selected per route.

Route::get('/posts/{post:slug}', [PostController::class, 'show']);

public function show(Post $post)
{
    return view('posts.show', compact('post'));
}

Fallback and inspection

A fallback route handles requests that no other route matched. List everything currently registered with Artisan.

Route::fallback(fn () => response()->view('errors.404', [], 404));
php artisan route:list
php artisan route:list --path=admin