Next.js Redirects and Rewrites
Websites change over time. Pages move, products retire, and old links still live in search results and bookmarks. Redirects and rewrites handle these changes without breaking the visitor experience. Both tools send a request to a different destination, but they behave differently in the browser.
The Everyday View
A redirect works like a forwarding sign on a shop door. The sign says, "We moved to a new street. Please walk there." The visitor sees the new address and walks to it.
A rewrite works like a receptionist. A visitor asks for Room A. The receptionist quietly sends a colleague from Room B, and the visitor never learns about the swap. The address the visitor asked for stays the same.
Redirect vs Rewrite at a Glance
REDIRECT Browser asks /old-page Server says "Go to /new-page" Browser asks /new-page Address bar shows /new-page REWRITE Browser asks /old-page Server fetches content of /new-page quietly Browser gets the content Address bar still shows /old-page
Redirects in the Config File
The file next.config.js accepts an async redirects function. Each rule lists a source, a destination, and a permanent flag.
module.exports = {
async redirects() {
return [
{
source: '/old-blog',
destination: '/blog',
permanent: true,
},
{
source: '/sale',
destination: '/offers/winter',
permanent: false,
},
];
},
};Permanent or Temporary
A permanent redirect uses status code 308. Browsers and search engines remember it and treat the new address as the real home of the page. A temporary redirect uses status code 307. Browsers keep asking the old address because the move may reverse later. Use permanent redirects for lasting moves and temporary redirects for short campaigns.
Dynamic Patterns
Rules accept path parameters. A single rule can forward a whole family of old URLs.
{
source: '/articles/:slug',
destination: '/blog/:slug',
permanent: true,
}A visitor who opens /articles/learn-react lands on /blog/learn-react.
Redirects Inside Code
Sometimes a decision depends on data. A signed-out visitor should land on the login page, and an unknown product should land on a catalog page. The redirect function from next/navigation handles these cases inside Server Components, Server Actions, and Route Handlers.
import { redirect } from 'next/navigation';
export default async function Dashboard() {
const user = await getCurrentUser();
if (!user) {
redirect('/login');
}
return <h1>Welcome back, {user.name}</h1>;
}The permanentRedirect function from the same package sends a permanent response. Call either function outside of a try/catch block because both work by throwing a special signal that Next.js catches.
Rewrites in the Config File
Rewrites live beside redirects in the config file. They map a visible path to a hidden destination.
module.exports = {
async rewrites() {
return [
{
source: '/help',
destination: '/support/faq',
},
];
},
};Visitors open /help and read the content of /support/faq. The address bar keeps showing /help.
Proxying an External Service
A rewrite can point to a different website. This pattern hides the external address and avoids browser cross-origin restrictions during development.
{
source: '/api/weather/:path*',
destination: 'https://api.example.com/weather/:path*',
}Requests to /api/weather/today travel to the outside service, and the response returns under your own domain.
Gradual Adoption of a New Site
Teams that move from an old platform to Next.js can rewrite unknown paths to the old site. Pages already built in Next.js respond first. Everything else falls through to the legacy server. This approach lets a migration happen one page at a time.
Choosing the Right Tool
| Need | Best Tool |
|---|---|
| Page moved for good | Permanent redirect |
| Short promotion link | Temporary redirect |
| Send signed-out users to login | redirect() in code |
| Friendly URL for an internal path | Rewrite |
| Hide an external service address | Rewrite |
Common Mistakes
Redirect Loops
Rule A sends visitors to B, and rule B sends them back to A. Browsers stop after several hops and show an error. Review rules together to catch loops early.
Wrong Permanent Flag
Browsers cache permanent redirects aggressively. A mistaken permanent rule can linger on visitor devices for a long time. Start with temporary redirects while you test, and switch to permanent after you confirm the result.
Forgetting a Server Restart
Changes to next.config.js need a restart of the development server. Stop the server and run npm run dev again after every edit.
Quick Summary
Redirects tell the browser to visit a new address. Rewrites serve different content under the original address. Use config rules for fixed patterns and the redirect function for decisions that depend on live data.
