Skip to main content

Basic routing

The most basic Laravel route accepts a URI and a closure, letting you define a route and its behavior without complex configuration files:
use Illuminate\Support\Facades\Route;

Route::get('/greeting', function () {
    return 'Hello World';
});

Default route files

All Laravel routes are defined in the files inside the routes/ directory. Laravel automatically loads these files based on the configuration in bootstrap/app.php. Define browser-facing routes in routes/web.php. Routes in this file have the web middleware group applied, which provides session handling, CSRF protection, and cookie encryption:
use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);

API Routes

If your application will also offer a stateless API, you may enable API routing using the install:api Artisan command:
php artisan install:api
The install:api command installs Laravel Sanctum, which provides a robust, yet simple API token authentication guard which can be used to authenticate third-party API consumers, SPAs, or mobile applications. In addition, the install:api command creates the routes/api.php file:
Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');
Of course, you are free to omit the auth:sanctum middleware on routes that should be publicly accessible. The routes in routes/api.php are stateless and are assigned to the api middleware group. Additionally, the /api URI prefix is automatically applied to these routes, so you do not need to manually apply it to every route in the file. You may change the prefix by modifying your application’s bootstrap/app.php file:
->withRouting(
    api: __DIR__.'/../routes/api.php',
    apiPrefix: 'api/admin',
    // ...
)

Available HTTP methods

The router can register routes that respond to any HTTP verb:
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
To respond to multiple HTTP verbs, use match or any:
Route::match(['get', 'post'], '/', function () {
    // ...
});

Route::any('/', function () {
    // ...
});
HTML forms in the web routes file that send POST, PUT, PATCH, or DELETE requests must include the @csrf Blade directive. Requests without it will be rejected.

Returning a view

When a route only needs to return a view, use Route::view for a concise definition:
Route::view('/welcome', 'welcome');

// Passing data to the view
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Route parameters

Required parameters

Capture segments of the URI by defining route parameters wrapped in {}. The captured values are passed as arguments to the route callback:
Route::get('/user/{id}', function (string $id) {
    return 'User ID: ' . $id;
});
You can define multiple parameters:
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
    return "Post {$postId}, comment {$commentId}";
});
Route parameters cannot contain the / character.

Optional parameters

Make a parameter optional by adding ? after its name and providing a default value for the corresponding argument:
Route::get('/user/{name?}', function (?string $name = null) {
    return $name ?? 'Guest';
});

Route::get('/user/{name?}', function (?string $name = 'Guest') {
    return $name;
});

Regular expression constraints

Constrain the format of a route parameter using the where method:
Route::get('/user/{id}', function (string $id) {
    // ...
})->where('id', '[0-9]+');

Route::get('/user/{name}', function (string $name) {
    // ...
})->where('name', '[a-zA-Z]+');
Commonly used patterns have convenience methods:
Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->whereNumber('id')->whereAlpha('name');

Named routes

Named routes let you reference a route by name when generating URLs or redirects, so you don’t need to hard-code URLs:
Route::get('/user/profile', function () {
    // ...
})->name('profile');

Generating URLs to named routes

Use the route helper to generate a URL from a route name:
// Generate a URL
$url = route('profile');

// Generate a URL with parameters
$url = route('user.show', ['id' => 1]);

Redirecting to named routes

return redirect()->route('profile');

Route groups

Group related routes to share middleware, controllers, prefixes, and other attributes without repeating them on each route.

Middleware

Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', function () {
        // Only accessible to authenticated users
    });

    Route::get('/account', function () {
        // Only accessible to authenticated users
    });
});

Controllers

Group routes that share the same controller:
use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function () {
    Route::get('/orders', 'index');
    Route::post('/orders', 'store');
    Route::get('/orders/{id}', 'show');
});

Prefixes

Add a common URI prefix to a group of routes:
Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // Accessible at /admin/users
    });
    Route::get('/posts', function () {
        // Accessible at /admin/posts
    });
});

Name prefixes

Prefix the name of every route in a group:
Route::name('admin.')->group(function () {
    Route::get('/users', function () {
        // Route named "admin.users"
    })->name('users');
});

Resource routes

For controllers that handle CRUD operations on a resource, Route::resource registers all the standard routes in one line:
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class);
This single declaration creates the following routes:
VerbURIActionRoute name
GET/photosindexphotos.index
GET/photos/createcreatephotos.create
POST/photosstorephotos.store
GET/photos/{photo}showphotos.show
GET/photos/{photo}/editeditphotos.edit
PUT/PATCH/photos/{photo}updatephotos.update
DELETE/photos/{photo}destroyphotos.destroy
To register only a subset of these routes, use only or except:
Route::resource('photos', PhotoController::class)->only(['index', 'show']);

Route::resource('photos', PhotoController::class)->except(['create', 'store', 'update', 'destroy']);

Listing defined routes

Display all registered routes with the Artisan command:
php artisan route:list
Include middleware information:
php artisan route:list -v
Filter routes by URI prefix:
php artisan route:list --path=user

Next steps

Blade templates

Learn how to use Laravel’s Blade templating engine to build dynamic views.
Last modified on June 8, 2026