skip to content

In Laravel, what do Route::view and Route::redirect register, and what defaults and reserved parameter names do they carry?

level: juniorimportance: should knowfreq 35%

answer

  1. shortcut routes, no controller
  2. view: GET and HEAD via ViewController
  3. redirect: any verb, 302 default
  4. permanentRedirect sends 301
  5. reserved: view, data, status, headers, destination

basics

~10 s

Route::view registers a GET/HEAD route that renders a Blade view with optional data; Route::redirect registers a route for every verb that redirects with 302 unless you pass a status; Route::permanentRedirect sends 301.

solid answer

~30 s

Both are shortcuts that save writing a closure or controller. `Route::view('/about', 'pages.about', ['since' => 2012])` registers a GET/HEAD route handled by the framework's `ViewController`; URI parameters are merged into the view data, so `{cuisine}` arrives as `$cuisine`. `Route::redirect('/recipe/{slug}', '/recipes/{slug}')` is registered with `Route::any`, answers every verb, and sends a `302` unless you pass a third argument; `Route::permanentRedirect` sends `301`. Parameters in the source URI are substituted into the destination. Because the shortcuts store their settings as route defaults, some parameter names are reserved: `view`, `data`, `status` and `headers` for view routes, `destination` and `status` for redirect routes.

code

php · 12 lines
php
<?php

// routes/web.php
use Illuminate\Support\Facades\Route;

Route::view('/about', 'pages.about', ['foundedIn' => 2012])->name('about');

// Old recipe URLs, moved for good
Route::permanentRedirect('/recipe/{slug}', '/recipes/{slug}');

// Temporary: the seasonal menu lives on the recipes index for now
Route::redirect('/seasonal', '/recipes');

go deeper

for a junior

Remember that Route::view renders a view without a controller and Route::redirect sends a 302 unless told otherwise.

for a middle

Explain that both shortcuts store settings as route defaults, which is why some parameter names are reserved, and that redirect routes answer every verb.

for a senior

Plan URL migrations with parameter-carrying redirects, pick 302 versus 301 deliberately, and move pages to controllers once they need per-request logic.

for a principal

Treat URL changes as a contract with users and search engines, and decide how long redirect routes are kept and who owns them.

## Why the shortcuts exist Many routes do nothing but render a static page or send the visitor somewhere else. Writing a closure for each one adds noise, so Laravel's router provides two **shortcut routes**: - **`Route::view($uri, $view, $data = [], $status = 200, $headers = [])`** renders a view. - **`Route::redirect($uri, $destination, $status = 302)`** and **`Route::permanentRedirect($uri, $destination)`** redirect. Both return a normal `Illuminate\Routing\Route`, so you can chain `->name(...)`, `->middleware(...)` or `->where(...)` exactly as on any other route. ## How Route::view works `Route::view` calls `Route::match(['GET', 'HEAD'], $uri, ViewController::class)` and stores `view`, `data`, `status` and `headers` as **route defaults**. When a request arrives, `ViewController` does three things: 1. Collects the route's parameters, minus the four reserved keys. 2. Merges them into the data array, so a URI segment becomes a **view variable**. 3. Returns `response()->view($view, $data, $status, $headers)`. ```php Route::view('/about', 'pages.about', ['foundedIn' => 2012]); Route::view('/cuisines/{cuisine}', 'recipes.cuisine')->name('cuisines.show'); // resources/views/recipes/cuisine.blade.php can use {{ $cuisine }} ``` Because `view`, `data`, `status` and `headers` travel as route defaults, a URI parameter with one of those names would collide with the shortcut's own settings, so the docs reserve them. ## How Route::redirect works `Route::redirect` registers the URI with **`Route::any`**, which means the redirect answers all seven router verbs, and `route:list` shows it as `ANY`. It stores `destination` and `status` as route defaults and hands the request to the framework's `RedirectController`, which: 1. Treats the destination as a route template and fills in any parameters it shares with the source URI. 2. Returns a redirect response with the stored status. | Call | Status | Verbs answered | |---|---|---| | `Route::redirect('/menu', '/recipes')` | 302 Found | all seven | | `Route::redirect('/menu', '/recipes', 301)` | 301 | all seven | | `Route::permanentRedirect('/menu', '/recipes')` | 301 Moved Permanently | all seven | Parameter carry-over is what makes URL migrations cheap. A recipe site renaming its URLs can write one line: ```php Route::permanentRedirect('/recipe/{slug}', '/recipes/{slug}'); ``` A request to `/recipe/lemon-tart` is sent to `/recipes/lemon-tart`. The reserved names here are `destination` and `status`. ## Choosing between them and a real route - Use **`Route::view`** for pages with no per-request logic: about, terms, a static landing page. Once the page needs a query, move it to a controller. - Keep the data argument small and static: it is stored on the route itself, so it is fixed when routes are registered and, once routes are cached, serialized into the cache file. - Use **`Route::redirect`** for renamed or retired URLs. Choose **302** while you might still change your mind, and **301** once the move is final, because clients and search engines are allowed to remember a permanent redirect. - Named-route redirects inside controllers (`to_route()`, `redirect()->route()`) are a different tool: they build a response at runtime rather than registering a route. ## Recognising the shortcuts in route:list Shortcut routes are easy to miss in a large route file, but `php artisan route:list` gives them away: - A view route shows `GET|HEAD` and the action `Illuminate\Routing\ViewController`. - A redirect route shows `ANY` and the action `Illuminate\Routing\RedirectController`. - Their names, middleware and constraints appear like any other route's, because they are ordinary `Route` objects. This matters during audits: a forgotten `Route::redirect` that answers every verb on a URL you later reuse for a real endpoint will collide with the new route. Search the listing for `RedirectController` before reusing an old path, and delete redirects once traffic to the old URLs has died down. ## Pitfalls interviewers probe - **Assuming redirect routes are GET-only.** They answer POST too; a form posting to a retired URL is redirected, and the browser follows with a GET, so the submitted body is lost. - **Assuming 301 is the default.** It is 302 unless you pass a status or use `permanentRedirect`. - **Using a reserved name as a URI parameter**, such as `/orders/{status}` on a view route: the segment collides with the shortcut's own `status` setting. - **Expecting Route::view to accept a closure** for computed data. It takes a static array; computed data belongs in a controller or a view composer.

  • How does a Laravel redirect route carry a segment from the old URL into the new one?
    `RedirectController` treats the destination as a route template. It takes the source route's parameters, keeps those that appear as placeholders in the destination, and fills them in. So `Route::permanentRedirect('/recipe/{slug}', '/recipes/{slug}')` sends `/recipe/lemon-tart` to `/recipes/lemon-tart` without a controller.
  • When would you replace a Route::view route with a controller?
    As soon as the page needs anything computed per request: a query, the authenticated user's data, authorization, or caching logic. `Route::view` only passes a static array plus URI segments into the view, so logic would otherwise leak into the Blade template.

saying these in an interview costs you the question

  • Route::redirect sends a 301 by default
  • Redirect routes only answer GET requests
  • Route::view cannot pass any data to the view
  • A URI parameter named status is fine on a redirect route
  • Route::view routes cannot be named or given middleware