Routes often need to capture segments of the URI, such as an ID. Wrap parameter names in curly braces:
Route::get('/posts/{id}', function (string $id) {
return 'Post #' . $id;
});
// Optional parameter
Route::get('/posts/{id?}', function (?string $id = null) {
return $id ?? 'No ID provided';
});
// Multiple parameters
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
// ...
});
You can constrain a parameter's format with where():
Route::get('/user/{id}', [UserController::class, 'show'])->where('id', '[0-9]+');
Route model binding is one of Laravel's most convenient features — instead of manually looking up a model by ID, Laravel injects the model instance automatically when the parameter name matches a model's route key (usually id):
Route::get('/posts/{post}', function (Post $post) {
return $post->title;
});
If no Post with that ID exists, Laravel automatically returns a 404 response — no manual findOrFail() needed.