The redirect map

WordPress to Next.js Redirects: Build the Map, Choose the Status Code, Test Every Line

Nobody frames a redirect map and hangs it in the lobby. It is still the file that decides whether a WordPress to Next.js migration keeps its traffic. Every bookmark, backlink and ranking points at an old address, and each one needs a single, permanent answer.

October 8, 2026 · 9 min read

The short answer

List every old URL from your sitemaps, a crawl, Search Console, backlinks, server logs and any redirect plugin. Give each a destination, flatten old chains to one hop, and use permanent redirects, which Next.js sends as 308 and Google treats like a 301. Put patterns in next.config, move very large maps into Proxy, and test the full list before DNS changes.

On this page
  1. The most valuable file in the whole migration
  2. Six sources for the old side of the map
  3. The redirects your old plugins were quietly running
  4. 301, 308 and the status code Next.js sends
  5. next.config or Proxy: where a big map should live
  6. Chains, loops and redirects to nowhere useful
  7. Testing the map before and after DNS moves
  8. Redirect work by theme and by site type

The most valuable file in the whole migration

A new site gets judged on its design. A migration gets judged on whether the phone keeps ringing in the month after launch. Most of that comes down to one spreadsheet: old URL in column A, new URL in column B. If a page moved and the map does not say where, Google finds a 404, the link equity that page collected stops flowing, and a customer clicking an old link from a directory or an email lands on nothing.

The good news is that the work is mechanical. The bad news is that it is easy to underestimate. A WordPress site exposes many more URLs than it has pages, as the URL structure guide explains. Keeping your existing addresses wherever you can shrinks the map, because a URL that does not change needs no redirect. What remains is the list of real changes, and it deserves the same care as the code.

A redirect you forgot is a page you deleted.

Six sources for the old side of the map

No single tool sees every URL that matters. Sitemaps list what the SEO plugin thought was important. Crawlers find what is linked. Search Console shows what Google actually sends people to. Backlink data shows what other sites point at, including pages you deleted in 2019. Pull all of them and merge the list.

  • XML sitemaps from Yoast, Rank Math or whichever SEO plugin generated them, including the separate post, page, category and product sitemaps.
  • A full crawl of the live site, which turns up archives, paginated pages and attachment URLs the sitemaps skip.
  • Search Console's Pages and Performance reports, filtered to URLs with impressions or clicks in the last 16 months.
  • Backlink data listing the pages other sites link to, including ones that already 404 and could be rescued.
  • Server or CDN logs, which show the URLs real visitors and bots request, typos and all.
  • Your existing redirect table, whether it lives in a plugin, an .htaccess file or the host's control panel.

Give each row the same columns: old URL, new URL, status, source and a one-line reason. The reason column feels like bureaucracy until someone asks, a year later, why the old pricing page goes to the contact page.

The redirects your old plugins were quietly running

Most WordPress sites older than a few years already run redirects nobody remembers creating. The Redirection plugin keeps them in its own table and, according to its documentation, exports them as CSV, JSON, Apache .htaccess rules or Nginx rewrite rules. Rank Math and Yoast Premium have redirect managers of their own. Some hosts add rules at the server level. All of them stop working the moment WordPress is switched off.

Export every one of them and treat the export as part of the map. Then check three things. First, does the rule still point somewhere real, or does it send people to a page that has itself been deleted? Second, is it a regular expression? Redirection marks regex rules with a flag, and Next.js uses path-to-regexp syntax, which is close but not identical, so each pattern gets rewritten and tested rather than pasted. Third, is it a 302? Plenty of plugin rules were created as temporary and left that way for years. If the move was permanent, the new rule should say so.

301, 308 and the status code Next.js sends

WordPress plugins usually issue 301s. Next.js issues 308s. The redirects option in next.config takes a permanent flag: true sends a 308, false sends a 307. The Next.js documentation explains why. Browsers historically changed POST requests to GET when following a 301 or 302, and 307 and 308 exist to preserve the original method.

For search, the difference does not matter. Google's documentation groups 301 and 308 together as permanent redirects and says the indexing pipeline uses them as a signal that the target should be canonical. Temporary codes, 302 and 307 included, do not carry that signal. So the rule is simple: anything that moved for good gets permanent: true. If some old client or partner integration insists on a 301, Next.js accepts a statusCode property instead of permanent, though not both on the same rule.

Two more details from the Next.js docs are worth knowing. Query strings pass through to the destination, so /old-post/?utm_source=newsletter arrives at /new-post/?utm_source=newsletter with its tracking intact. And redirects are checked before the filesystem, which means a redirect rule will win over a page at the same path. That is helpful when you mean it and confusing when you do not.

The third option

Athena CMS, with AI agents on staff.

Not a theme and not a blank Next.js repo. The content system we put behind every custom site: plain fields, a real preview, every version kept, and AI agents that handle the chores a plugin only nags you about.

and 12 more agents. Two come with Athena; the rest are monthly add-ons.

The Athena CMS editor: plain fields with AI rewrite, a Publish box and revisions

next.config or Proxy: where a big map should live

There is more than one place to put redirects in a Next.js project, and the right one depends on how many rules you have and how often they change.

Where to put WordPress redirects in a Next.js project
Good forLimitsChanges need
redirects in next.configKnown lists and patterns, a few hundred rulesVercel caps config redirects at 1,024A rebuild and deploy
Pattern rulesWhole URL families, such as date foldersPatterns must be written and escaped carefullyA rebuild and deploy
Proxy with a lookupThousands of one-to-one rulesRuns on requests, so lookups must be fastA data update, no redeploy if stored outside the build
Host or CDN rulesDomain-level moves, http to https, wwwSeparate from the codebaseA change in the host's dashboard

Patterns do most of the heavy lifting. If every post moves from /2023/04/slug/ to /blog/slug/, one rule with a source of /:year(\d{4})/:month(\d{2})/:slug and a destination of /blog/:slug replaces hundreds of lines. The docs warn that characters such as parentheses, colons and question marks are special in a source and must be escaped when you mean them literally, and that forgetting the slash before a parameter can cause infinite redirects.

For maps beyond about a thousand one-off rules, the Next.js redirecting guide recommends a custom solution in Proxy, the file that Next.js 16 renamed from middleware. The map lives in a JSON file or a fast key-value store, Proxy checks each request against it, and the guide even shows a Bloom filter to avoid loading the full list on every request. Proxy runs after the config redirects, so the two can be combined: patterns in config, the long tail in Proxy.

Chains, loops and redirects to nowhere useful

Google's site move guidance asks for short chains, ideally no more than three hops and fewer than five, and notes that each hop adds latency. Our standard is one. After the map is drafted, resolve every destination: if column B is itself an old URL with its own redirect, replace it with the final address. Repeat until nothing points at something that moves.

Loops are the other failure. They usually come from two rules that disagree, often a trailing slash rule fighting a hand-written redirect, and they show up in the browser as too many redirects. Matching the old trailing slash style in next.config prevents most of them before they start.

Then resist the shortcut of sending every leftover URL to the home page. A redirect to an unrelated page tells Google nothing useful, and Search Console often reports such URLs as soft 404s. If a page had no traffic, no links and no close replacement, an honest 404 is the cleaner answer. If it had value, find the nearest real match: the category, the service or the newer article that covers the same question.

Testing the map before and after DNS moves

  1. 1

    Replay every old URL on staging

    Run the full list against the preview build with a crawler or a short script. Each URL should return 200 or exactly one permanent redirect.

  2. 2

    Check the destination, not just the code

    A 308 to the wrong page passes a status check and still loses the ranking. Compare final URLs against column B.

  3. 3

    Test query strings and odd cases

    Try campaign parameters, uppercase letters, missing trailing slashes and encoded characters, which old links contain more often than you would expect.

  4. 4

    Switch DNS and replay again

    Run the same list against the live domain within the first hour. Host and CDN rules sometimes behave differently from staging.

  5. 5

    Watch Search Console and the logs

    Check crawl errors and 404 reports daily for the first weeks and add rules for anything the inventory missed.

  6. 6

    Keep the rules

    Google advises keeping redirects for at least a year. We keep them for the life of the site, because old links never fully stop arriving.

On a site that runs Athena CMS, Argus keeps watching for broken links long after the launch checklist is filed, so a missed address shows up as a task instead of a silent loss. The full set of launch checks lives in migrating without losing SEO.

Redirect work by theme and by site type

The size of the map depends on what the old site generated. Builder themes create their own URL families: a Divi migration often includes the project post type, and an Avada migration can include portfolio items and FAQ entries. Lightweight themes such as GeneratePress or Astra add little of their own, so their maps are mostly posts, pages and archives.

Stores are the largest. Product, category, tag and filtered URLs all need decisions, covered in the WooCommerce to Next.js guide. Image files are a separate list again, because files that rank in Google Images have addresses of their own; see migrating WordPress images.

Every rebuild we run in Next.js ships with the map as a deliverable, tested before launch and handed over afterward. Your team edits pages in Athena CMS while the routing rules stay in code, reviewed and tested, which is where a list this important belongs.

Questions people ask before they call

Setting permanent: true in next.config sends a 308, and permanent: false sends a 307. Google treats 308 the same as 301 for indexing, so a 308 passes the same signal. If you need an actual 301 for an older client, Next.js lets you set statusCode on that rule instead of permanent.

Next.js does not publish a hard cap of its own, but platforms can. Vercel, for example, limits config redirects to 1,024. For larger maps, the Next.js docs recommend handling redirects in Proxy with a lookup table, which also lets you change rules without a full redeploy. Pattern rules often shrink a big map to a handful of lines.

Yes, with checking. Export them from the plugin as CSV or JSON, then review each one: remove rules that point at deleted pages, flatten chains, convert 302s that were really permanent, and rewrite regular expressions into the path syntax Next.js uses. We load the cleaned list into next.config or a Proxy lookup and test it.

Google's site move guidance says at least a year, and as long as possible. We keep them permanently. Redirects cost almost nothing to keep in a Next.js build, and old links in emails, directories and forum posts keep arriving for years. Removing them saves nothing and loses visitors.

Usually not. A redirect to an unrelated page does not help Google, and those URLs often show up as soft 404s in Search Console. Send a removed page to its closest real replacement, or let it return a 404 if nothing fits. Our Next.js development team makes that call row by row, using traffic and link data.

Keep reading

Free · No obligation

Get a redirect map you can trust

Tell us about your site. We will inventory every old URL, check your existing plugin redirects and show you the map before anything moves.

Which of these sounds like you? (pick any)

Rather talk now? Call (210) 346-0848.

CallGet a quote