In Laravel, how do you name a route with ->name() and build its URL with route(), including parameters and extra query keys?
answer
- chain ->name() on the definition
- route(name, parameters, absolute)
- named keys fill placeholders, list fills in order
- leftover keys become the query string
- unknown name: RouteNotFoundException
basics
~10 sChain ->name('franchise.orders.show') on the route, then call route('franchise.orders.show', ['order' => 42]); matching keys fill the placeholders, leftover keys become the query string, and the URL is absolute unless the third argument is false.
solid answer
~30 s`->name()` gives a route a name, and `route($name, $parameters = [], $absolute = true)` builds its URL. Keys that match placeholders fill them (`['order' => 42]` fills `{order}`), unnamed values fill the remaining placeholders in order, and any other string keys are appended as a query string, so `route('franchise.orders.show', ['order' => 42, 'tab' => 'items'])` gives `https://.../orders/42?tab=items`. Passing `false` as the third argument returns just the path. An unknown name throws `RouteNotFoundException` (`Route [x] not defined.`), and a missing required value throws `UrlGenerationException` listing the missing parameter. `Route::has('name')` checks whether a name exists, and names should be unique.
code
php · 13 lines<?php
use App\Http\Controllers\OrderController;
use Illuminate\Support\Facades\Route;
Route::get('/orders/{order}', [OrderController::class, 'show'])
->name('franchise.orders.show');
$absolute = route('franchise.orders.show', ['order' => 42, 'tab' => 'items']);
// https://example.com/orders/42?tab=items
$path = route('franchise.orders.show', ['order' => 42], false);
// /orders/42go deeper
Know how to chain ->name() and call route() with a parameters array, and that extra keys become the query string.
Explain how named and positional values fill placeholders, the absolute flag, and the two exceptions for unknown names and missing parameters.
Use Route::has for optional links, choose relative URLs where hosts vary, and treat name typos as failures caught by rendering tests.
Set a naming scheme that scales across teams and packages so names stay unique and predictable for years.
## Naming a route A **route name** is a stable identifier you can use instead of the URI. You add it by chaining `name()` onto the definition: ```php use App\Http\Controllers\OrderController; use Illuminate\Support\Facades\Route; Route::get('/orders/{order}', [OrderController::class, 'show']) ->name('franchise.orders.show'); ``` Points worth knowing: - Names are plain strings; the dotted `area.resource.action` style is a convention, not a rule. - `name()` **appends** to any name prefix inherited from a group, so inside `Route::name('franchise.')` you write only `->name('orders.show')`. - A string-backed enum case is accepted as the name as well. - Names should be **unique**; the docs say so explicitly, and duplicates cause subtle bugs. ## Building a URL with route() The global `route()` helper calls the URL generator's `route()` method. Its signature is `route($name, $parameters = [], $absolute = true)`. The generator fills the route's URI in a fixed order: 1. **Named keys first**: `['order' => 42]` replaces `{order}`. 2. **Unnamed values next**: a list such as `[42]`, or a single scalar `route('franchise.orders.show', 42)`, fills the remaining placeholders left to right. 3. **Absent optional placeholders** (`{status?}` with no value) are dropped from the URI. 4. **Leftover string keys** become the query string. 5. The result is **absolute** (scheme and host of the current request or configured root) unless `$absolute` is `false`. | Call | Result | |---|---| | `route('franchise.orders.show', ['order' => 42])` | `https://example.com/orders/42` | | `route('franchise.orders.show', 42)` | `https://example.com/orders/42` | | `route('franchise.orders.show', ['order' => 42, 'tab' => 'items'])` | `https://example.com/orders/42?tab=items` | | `route('franchise.orders.show', ['order' => 42], false)` | `/orders/42` | Values are encoded as needed, so a `?` or `#` inside a parameter does not break the URL. ## When generation fails Two exceptions cover the common mistakes: - **Unknown name**: `Symfony\Component\Routing\Exception\RouteNotFoundException` with the message `Route [franchise.order.show] not defined.` Typos in names surface here, at the call site, instead of as broken links. - **Missing required value**: `Illuminate\Routing\Exceptions\UrlGenerationException`, for example `Missing required parameter for [Route: franchise.orders.show] [URI: orders/{order}] [Missing parameter: order].` Both are thrown while rendering, so a Blade view with a bad `route()` call fails loudly in development and in tests. ## Checking that a name exists `Route::has('franchise.orders.show')` returns `true` when a route with that name is registered, and accepts several names, returning `true` only if all exist. Packages and shared layouts use it to render a link only when the host app defines the route. ## Naming conventions that scale A consistent scheme keeps names unique without anyone keeping a list: 1. **Area first**: `franchise.`, `admin.`, `api.`, applied once with a group name prefix. 2. **Resource next**: `orders.`, `stores.`. 3. **Action last**: `index`, `show`, `create`, `store`, `edit`, `update`, `destroy`, matching the controller method where there is one. The result, `franchise.orders.show`, reads like a path through the app and lets wildcard checks such as `routeIs('franchise.orders.*')` select a whole area. Teams that prefer typed names can use a string-backed enum case, since both `->name()` and `route()` accept one and read its value. ## A franchise dashboard example In a Blade view for the franchise dashboard: ```html <a href="{{ route('franchise.orders.show', ['order' => $order->id, 'tab' => 'items']) }}"> Order #{{ $order->id }} </a> ``` If the URI later moves from `/orders/{order}` to `/dashboard/orders/{order}`, every link built with `route()` follows automatically; only hardcoded paths would break. ## Pitfalls interviewers probe - **Expecting relative URLs by default.** `route()` is absolute unless the third argument is `false`; relative paths matter when the same markup is served on several hosts. - **Misspelling a key**: `['id' => 42]` for `{order}` leaves `{order}` unfilled, and the unused `id` would have become a query key, so the call throws for the missing `order` instead. - **Duplicate names**: `route()` silently resolves to only one of the routes. - **Assuming `route()` returns `null` for an unknown name.** It throws.
- What does Laravel's route() do when you pass ['id' => 42] for a route whose URI is /orders/{order}?The generator fills placeholders by key first, finds no `order` key, and has no unnamed value left to fill `{order}` by position. The placeholder stays in the URI, so it throws `UrlGenerationException` with `[Missing parameter: order]`. Rename the key to `order`, or pass the value unnamed as `[42]`.
- When would you ask route() for a relative path instead of an absolute URL?When the same markup is served under several hosts or behind a proxy that rewrites the host, or when a value is stored and later rendered elsewhere. `route('franchise.orders.show', ['order' => 42], false)` returns `/orders/42`, which the browser resolves against whatever host served the page.
saying these in an interview costs you the question
- route() returns a relative path by default
- Extra keys passed to route() are silently discarded
- route() returns null when the name does not exist
- Route names are automatically unique, so duplicates cannot happen
- Parameters must always be passed as an associative array