Skip to content
hubreven
SEO5 min read

Building a 301 redirect map: the URLs that break migrations

A 301 redirect map should be built from a full crawl, Search Console impressions and analytics sessions combined, cover query strings and paginated URLs explicitly, contain no chains longer than one hop, and be tested against staging by asserting both the 301 status and the exact destination before launch.

By HubReven

Most posts on this term show a two column spreadsheet and a plugin screenshot.

The spreadsheet is not the hard part. The hard part is that the list on the left is incomplete, and you will not find out which rows are missing until traffic has already gone.

Build the list from three sources

One source is never enough, because each one is blind to something different.

SourceFindsMisses
Full crawlEverything currently linkedOrphans that still rank
Search Console, 12 months of impressionsPages that rank, including forgotten onesPages with traffic but no search impressions
Analytics, 12 months of sessionsPages with direct or referral trafficPages with links but no visits yet

Export all three, deduplicate, and normalise before comparing: lowercase the host, decide on trailing slashes, and strip session parameters. Otherwise you will get thousands of false unique URLs and miss the real ones in the noise.

The combined list is routinely two to four times the size of the sitemap. That difference is the traffic that quietly disappears in most migrations.

Assign every URL one of three outcomes

Maps one to one. To the closest equivalent page on the new site. Most rows.

Retired. Redirect to the nearest relevant parent. Not the homepage. A redirect from a specific page to the homepage is treated as a soft 404 and passes essentially nothing, which makes it functionally identical to letting it 404 while looking like you handled it.

Unchanged. The best outcome, and the one to maximise. Every URL you do not change is a row that cannot break.

Leave a column for "decided by" and "date". Six months later when a page is missing, you will want to know whether it was an oversight or a decision.

The categories that get forgotten

Query strings. Faceted and sorted URLs (?colour=blue, ?page=3, ?sort=price) accumulate links and sometimes rank. Decide explicitly whether the new site preserves the parameter, canonicalises it away, or ignores it, then make the redirect rules preserve or strip parameters on purpose. Server rules that silently drop the query string are the default, and the default is usually wrong for filtered category pages.

Pagination. /blog/page/2 through /blog/page/14 are indexed and nobody thinks about them. If pagination changes shape, each one needs a destination. Sending them all to page one is acceptable. Sending them to a 404 is not.

Trailing slashes and case. Pick a convention, enforce it at the edge, and make sure the non canonical form redirects in a single hop rather than into the rest of your map.

Encoded characters. Older platforms produce URLs with spaces, accents and uppercase letters. They are ugly and they still get requested.

Uploaded files. PDFs, images and documents that are linked from other sites. They are not pages, so crawlers configured for HTML miss them, and they often carry the best links on the domain.

Flatten every chain

The quiet killer.

You redirect A to B in this migration. But B was already redirecting to C from the migration two years ago. Now every request walks a chain, each hop costs a little signal and crawl budget, and enough hops get abandoned entirely.

Before launch, run your own map through a crawler and assert that every source URL reaches its destination in exactly one hop. Where a chain exists, rewrite the first rule to point directly at the final destination. Then check for the other failure mode: loops, where A points at B and B points back at A, usually created by a trailing slash rule fighting a redirect rule.

Test against staging with assertions, not eyeballs

This is the step that separates migrations that hold from migrations that do not.

Run the complete old URL list against the staging environment and assert two things per row:

  1. The response status is 301, not 302 and not 200.
  2. The final destination matches the expected destination exactly.

"It redirects somewhere" is how a dozen unrelated pages end up on the homepage. A script that outputs a pass or fail per row takes an afternoon to write and catches what manual spot checking never will.

Also assert the negative: a URL that should 404 does return 404. A catch all rule that redirects everything to the homepage looks like success in a spot check and destroys the site's crawl efficiency.

Ship it at the edge, live from second one

Implement at the server or CDN layer rather than in application code where you can. It is faster, it survives application errors, and it does not depend on a plugin database that can be lost in a deployment.

There is no acceptable window where old URLs return 404. The map goes live in the same deploy as the new site.

Then submit the new sitemap in Search Console, keep the old sitemap resolving for a few weeks so the crawler has a list of old URLs to walk, and start the four weeks of monitoring that tell you whether it worked.

Keep the map

Do not delete it after launch. It is the document that explains why a URL behaves the way it does, and it is the input to the next migration. The chains you are flattening today exist because somebody threw the last one away.

And if the new site is slower than the one it replaced, the redirects were not the problem. That needs a budget enforced in the build.

Frequently asked questions

Should I use 301 or 302 redirects for a migration?

  1. A 302 signals the move is temporary and search engines may keep the old URL indexed. Use 302 only when the move genuinely is temporary, such as a seasonal page.

How long should redirects stay in place?

Indefinitely. They cost nothing to keep and old links keep arriving for years. Removing them is a cleanup task with no upside and a real downside.

Is it bad to have a lot of redirects?

A large map is fine. A large number of chains is not. The cost is per hop, not per rule, so flattening matters far more than reducing the row count.

Can I just use a catch all redirect to the homepage?

No. It resolves your 404 report and destroys the signal from every page it swallows. Search engines treat an irrelevant homepage redirect as a soft 404.

Get the next one

One email a month. Unsubscribe anytime.