->name('products.show') names a route, and route() turns a name and parameters into a URL, so moving /products/{product} to /p/{product} breaks no links. Names must be unique; the dotted style matches what resource routes generate (Prefixes and Subdomains). curl 3,008 -s http://127.0.0.1:8303/links | jq 133,477 . shows the variations:
Route::get('/links', fn () => [
'index' => route('products.index'),
'show' => route('products.show', ['product' => 2]),
'query' => route('products.show', ['product' => 2, 'ref' => 'mail']),
'relative' => route('products.show', 2, absolute: false),
'shop' => route('storefront', ['shop' => 'acme']),
'admin' => route('admin.orders.show', 3),
]);Output
{
"index": "http://127.0.0.1:8303/products",
"show": "http://127.0.0.1:8303/products/2",
"query": "http://127.0.0.1:8303/products/2?ref=mail",
"relative": "/products/2",
"shop": "http://acme.bookshop.test:8303",
"admin": "http://127.0.0.1:8303/admin/orders/3"
}Unknown keys become the query string, and a model can stand in for its ID. Without a request, as in a queued job or Tinker, URLs use APP_URL: the same call printed the skeleton's http://localhost:8000. to_route('products.index') redirects by name, and request()->routeIs('admin.*') tests the current route, handy for highlighting the active menu link.