Route::name
Names a route, or prefixes the names of every route inside a group.
name(BackedEnum|string $value): Illuminate\Routing\RouteRegistrarParameters
| Parameter | Type | Description |
|---|---|---|
$$value | BackedEnum|string | The name, or the prefix when used before group(). A prefix must include its own trailing separator, conventionally a dot. A backed enum is accepted and its value is used. |
Return value
Illuminate\Routing\RouteRegistrarA RouteRegistrar, so the call chains into group() or into further attribute methods. Chained onto a route definition instead — Illuminate\Routing\Route::name() — it returns that route and appends to whatever name prefix is in scope.
Errors
Nothing at registration. Calling route() or redirect()->route() with a name that was never registered throws Symfony\Component\Routing\Exception\RouteNotFoundException.
A named route is a stable handle for a URL. route('profile'), redirect()->route('profile') and to_route('profile') all resolve through it, which means the URI can change without touching a single view. Route names should always be unique.
Two roles, one method
Chained onto a definition, ->name('profile') names that route. Called before group(), Route::name('admin.') is a prefix that is prepended to every name inside, and nested groups append in order.
Passing parameters
Extra values go in the second argument to route(). Keys matching route parameters are substituted into their positions; anything left over becomes query string. Inside middleware, $request->route()->named('profile') tests the current route's name.
What trips people up
- The separator is yours. The prefix is prepended exactly as given, so
Route::name('admin')producesadminusers, notadmin.users. - Names are global. A web
photos.indexand an APIphotos.indexcollide silently — the later registration wins. - Route caching does not fix a bad name, but a stale cache does hide a new one; run
route:clearwhen a name you just added is "not defined".
Example
<?php
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
Route::get('/user/{id}/profile', [UserController::class, 'show'])->name('profile');
// As a group prefix — note the trailing dot.
Route::name('admin.')->group(function () {
Route::get('/users', [UserController::class, 'index'])->name('users');
});
echo route('profile', ['id' => 1]);
echo PHP_EOL;
echo route('profile', ['id' => 1, 'photos' => 'yes']);
echo PHP_EOL;
echo route('admin.users');
// http://example.com/user/1/profile
// http://example.com/user/1/profile?photos=yes
// http://example.com/admin/usersWhen to use it
- Link to a URL from Blade with route() so the path can change freely later.
- Prefix every route in an admin section with admin. in one place.
- Redirect after a form submission with to_route('photos.show', $photo).
- Detect the active navigation item by testing $request->route()->named('...').
Frequently asked questions
Why does route('admin.users') throw RouteNotFoundException?
The name was never registered under that exact string — most often because the group prefix was written as 'admin' without its trailing dot, producing 'adminusers'. A stale route cache can also hide a newly added name; run php artisan route:clear.
How do I add query string values to a generated URL?
Pass them in the same array as the route parameters. Keys that match route parameters are substituted into the path, and everything left over is appended as a query string.
Can two routes share a name?
They should not. Route names must be unique; if two registrations use the same name the later one wins and the earlier route becomes unreachable through route().
More examples
Names, prefixes and redirects together
Nested name prefixes append in registration order, so the leaf route named simply 'show' resolves as admin.reports.show. The commented lines show that route(), redirect()->route() and to_route() all take the same name and parameter array, and that a single non-array value is accepted as the first parameter.
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('admin')->name('admin.')->group(function () {
Route::prefix('reports')->name('reports.')->group(function () {
Route::get('/{year}', [ReportController::class, 'show'])
->whereNumber('year')
->name('show');
});
});
// Three equivalent ways to send the user there:
// return redirect()->route('admin.reports.show', ['year' => 2026]);
// return to_route('admin.reports.show', ['year' => 2026]);
// <a href="{{ route('admin.reports.show', 2026) }}">Report</a>
echo route('admin.reports.show', ['year' => 2026]);
// http://example.com/admin/reports/2026Checking the current route's name
named() answers whether the matched route carries a given name, which is how middleware and views branch on the current page without comparing URL strings. request()->routeIs() is the request-level equivalent and accepts wildcards such as 'admin.*'.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class TrackProfileVisits
{
public function handle(Request $request, Closure $next): Response
{
if ($request->route()->named('profile')) {
// Only runs for the route named 'profile'...
}
return $next($request);
}
}
// In Blade, the same idea highlights active navigation:
// <a href="{{ route('admin.users') }}" @class(['active' => request()->routeIs('admin.users')])>
echo request()->route()->getName();
// profile
Discussion