What are your options for nextjs redirects?
Next.js gives you three places to put redirects: the redirects function in next.config.js, middleware that runs before a request reaches a page, and your host's own redirect layer, such as Vercel project settings or Cloudflare. A fourth option, redirect calls inside a page, is for app logic rather than migrations.
For a site migration, the choice depends on how many rules you have and who maintains them. Redirects are one step in a wider plan, so pair this guide with our website migration SEO checklist. Here we compare the options and show how to set up each one.
Option | Best for | Scales to big maps? | Who edits it |
|---|---|---|---|
next.config.js redirects | Most sites, patterns and a few hundred rules | Gets unwieldy | Developers, via code review |
Middleware lookup | Large migration maps, data-driven rules | Yes | Developers, or editors via a data file |
Vercel or host config | Domain-level and simple path rules | Depends on plan | Developers or ops |
Cloudflare redirect rules | Old domains, bulk lists, sites in front of any host | Yes, with bulk lists | Ops or developers |
redirect() in a page | Logic like auth or moved records | Not intended for it | Developers |
How do you set up a Next.js 301 redirect in next.config?
You set up a Next.js 301 redirect by adding an async redirects function to next.config.js that returns an array of rules. Each rule has a source path, a destination, and a permanent flag. Next.js applies these before it checks pages or static files.
Open next.config.js
Add an async function called redirects to the exported config object. It returns an array.
Add a rule
Each rule is an object with source, such as /old-pricing, destination, such as /pricing, and permanent set to true.
Choose the status code
Permanent: true returns a 308 and false returns a 307. If you need a literal 301, set statusCode to 301 instead of permanent.
Use patterns for folders
A source like /post/:slug with destination /blog/:slug moves a whole folder in one rule. A trailing star on the parameter matches nested paths.
Deploy and test
Redirects in the config only apply after a build. Request each old URL and check for one hop and a 200 at the end.
The Next.js documentation for the redirects option covers matching on headers, cookies and query strings, plus regex paths. For migrations, simple path rules and parameters handle almost everything.
When should you use a nextjs middleware redirect?
Use a nextjs middleware redirect when your migration map is too large or too dynamic for the config file. Middleware runs on matching requests before rendering, looks up the incoming path in a table, and returns a redirect if it finds a match.
The Next.js docs include a section on managing redirects at scale, which describes this pattern: keep the map in a data store or generated file, and check it in middleware. That way the map can be regenerated from your 301 redirect map template spreadsheet without editing the config by hand.
- Keep the matcher narrow. Only run middleware on paths that could be old URLs, so normal pages aren't slowed down.
- Return a 301 or 308 explicitly. The redirect helper in middleware accepts a status code.
- Normalize before lookup. Lowercase the path and strip trailing slashes so small differences don't miss.
- Log misses. A 404 on an old-looking path is a row you forgot to map.
Hypothetical example: a 3,000-row map from a WordPress move
For example, suppose a content site moves from WordPress to Next.js and its old URLs use dates, like /2022/04/slug. The new site uses /blog/slug. A pattern rule can't drop the date reliably for every post, so the team exports a map of old to new paths from the crawl.
Instead of 3,000 entries in next.config.js, they generate a JSON lookup at build time and check it in middleware that only matches paths starting with a four-digit year. Category and tag archives get a handful of pattern rules in the config. Both layers are tested against the full old URL list before launch.
When are Vercel redirects or host-level rules better?
Vercel redirects and other host-level rules are better when the redirect doesn't belong to the app at all. The classic case is an old domain after a rebrand: it should redirect even if the Next.js app is mid-deploy or moved to another host.
Vercel lets you configure redirects in project settings and in a vercel.json file, and Cloudflare offers redirect rules and bulk redirect lists for any domain proxied through it. Check each provider's current docs for limits on your plan. Our guide to domain change SEO explains why the old domain should keep redirecting permanently, and our subdomain to subfolder migration guide covers proxies and redirects across hosts.
What are the common mistakes with Next.js redirects?
The common mistakes with Next.js redirects are chains, conflicts with trailing-slash settings, and rules that never get tested against the real old URL list. Each one is easy to miss in a code review.
- Temporary by accident. Permanent: false returns a 307, which tells Google to keep the old URL indexed.
- Overlapping patterns. Rules are checked in order, so put specific rules above broad ones.
- Redirecting to the homepage. Map each old URL to its closest match instead.
- Forgetting query strings. Campaign URLs with parameters should still land on the right page.
- Skipping verification. Crawl the old URL list after every deploy that touches redirects.
Which Next.js redirect option should you choose?
Choose next.config.js for patterns and up to a few hundred rules, middleware for large or generated maps, and host-level rules for anything domain-wide. Many migrations end up using two layers: patterns in the config and a domain rule at the host.
If you're moving away from Next.js instead, the rules have to be recreated on the new platform. Our guides to Framer redirects and Next.js to Framer migration cover that direction.
