Laravel Magazine
Route::redirect() and Route::permanentRedirect(): Quick, Declarative Redirects

Route::redirect() and Route::permanentRedirect(): Quick, Declarative Redirects

Eric Van Johnson ·

Renamed a page, merged two features into one URL, or just need /docs to send people to /documentation? It's tempting to write a controller for this, but Laravel has a one-liner for exactly this case.

The pattern people reach for first

Route::get('/docs', function () {
    return redirect('/documentation');
});

It's not wrong, but it's a closure route living in a file full of controller references, and it defaults to a 302 (temporary) redirect whether you meant that or not.

Route::redirect()

Route::redirect('/docs', '/documentation');

Same result, no closure, no controller. By default this issues a 302. Pass a third argument for a different status code:

Route::redirect('/old-pricing', '/pricing', 301);

Route::permanentRedirect()

For the common case of "this URL is gone for good, tell search engines and browsers to stop asking," there's a dedicated helper that's really just redirect() with the status locked to 301:

Route::permanentRedirect('/blog/old-post-slug', '/blog/new-post-slug');

Using the named helper instead of remembering to pass 301 every time makes the intent obvious to the next person reading your routes file — and to you, six months from now.

Where these earn their keep

A few real situations where this shows up constantly:

// Consolidating a legacy marketing site's URL structure into the app
Route::permanentRedirect('/about-us', '/about');
Route::permanentRedirect('/contact-us', '/contact');

// Short, memorable URLs for campaigns that point somewhere less catchy
Route::redirect('/webinar', '/events/quarterly-product-webinar-2026');

// Handling a renamed feature without breaking bookmarks
Route::permanentRedirect('/settings/notifications', '/settings/alerts');

The one gotcha

Route parameters aren't forwarded automatically. Route::redirect('/user/{id}', '/profile/{id}') will not substitute {id} for you — for anything with dynamic segments, you're back to a real controller or closure route that reads the parameter and builds the target URL explicitly. These helpers are for static, fixed-path redirects only, which covers a surprising amount of real-world cruft without needing a single extra class.

Stay Updated

Subscribe to our newsletter

Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.

Weekly articles
We send a new issue of the newsletter every week on Friday.
No spam
We'll never share your email address and you can opt out at any time.