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

NeedBest Tool
Page moved for goodPermanent redirect
Short promotion linkTemporary redirect
Send signed-out users to loginredirect() in code
Friendly URL for an internal pathRewrite
Hide an external service addressRewrite

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.