How to Set Up 301 Redirects Without Losing SEO

Redirect types, migration mapping, server config, and testing — without the traffic drop

July 2, 2026 · 13 min read
How to Set Up 301 Redirects Without Losing SEO

A bad redirect setup is one of the few SEO mistakes that can erase years of ranking work in a single deploy. I've watched a site lose 60% of its organic traffic after a migration because half the redirects pointed to the homepage and the other half chained through three hops.

The fix isn't complicated. 301 redirects pass link equity, Google has confirmed this since 2016, and the mechanics are well documented. What kills sites is sloppy execution: wrong status codes, missing URL maps, chains nobody tested. This guide covers the whole job — picking the right redirect type, mapping old URLs to new ones, implementing at the server, CMS, or CDN level, and verifying everything with curl before Google ever sees it.

TL;DR: Use 301 for permanent moves and 302/307 for temporary ones. Build a full old-URL → new-URL map before any migration. Redirect each page to its closest equivalent, never the homepage. Keep chains to one hop, test with curl -I, keep redirects live for at least a year, and watch Search Console for 404s after launch.


What 301, 302, 307, and 308 Actually Mean

A 301 tells browsers and crawlers the page has moved permanently. A 302 says the move is temporary. 307 and 308 are their stricter modern versions that forbid changing the HTTP method during the redirect. That method detail matters for forms and APIs, not much for regular page moves.

Here's the full picture:

Code Meaning Method preserved? Search engines
301 Moved permanently No (POST may become GET) New URL gets indexed, signals transfer
302 Found (temporary) No (POST may become GET) Old URL usually stays indexed
307 Temporary redirect Yes Treated like 302
308 Permanent redirect Yes Treated like 301

For a content site, the decision is simple. Page moved for good? 301. Page coming back — a sale landing page, A/B-style campaign URL, seasonal page? 302. The 307/308 variants only matter when POST requests hit the redirected URL, which is rare for blog posts and marketing pages but real for API endpoints. If your /api/v1/posts endpoint moves, a 308 keeps POST requests as POSTs instead of silently converting them to GETs.

One trap: 301s are cached aggressively by browsers, often with no expiry. If you ship a wrong 301, visitors who hit it keep getting redirected even after you fix the config. That's why I test permanent redirects as 302 first on anything risky, then flip to 301 once confirmed.


How Does Google Treat Redirects in 2026?

Google passes full PageRank through all 3xx redirects — Gary Illyes confirmed in 2016 that "30x redirects don't lose PageRank anymore." But signal consolidation isn't instant. Expect weeks to months before the new URL fully inherits the old one's rankings, and keep redirects live for at least a year.

The old SEO folklore said 301s leaked around 15% of link equity per hop, like a damping factor. Google killed that rule in 2016. Today a 301, 302, 307, or 308 all pass equity — Google treats a long-lived 302 as a 301 eventually anyway.

What still costs you:

  1. Time. Google has to recrawl the old URL, follow the redirect, recrawl the new URL, and consolidate signals. John Mueller has said this can take months for large sites.
  2. Relevance mismatch. Redirecting /blog/laravel-tips to your homepage doesn't transfer topical signals. Google treats irrelevant mass redirects as soft 404s — equity gone.
  3. Removed redirects. Google recommends keeping redirects in place for at least one year. Drop them earlier and any signals not yet consolidated are lost, along with every backlink pointing at the old URL.

So the rule is: redirect each old URL to its closest living equivalent, and leave the redirect up long after you think it's done its job. Internal linking hygiene matters here too — it's one of the checks in our CMS SEO checklist, because a CMS that lets 404s and orphan URLs pile up silently makes every migration worse.


Build a Redirect Map Before You Migrate

A redirect map is a two-column spreadsheet: every old URL on the left, its new destination on the right. Build it before changing anything, get it reviewed, and treat it as the single source of truth for the migration.

Skipping this step is how migrations go wrong. Here's the process I use:

  1. Crawl the current site. Export every indexable URL with Screaming Frog or your sitemap. Don't trust memory — crawl.
  2. Pull URLs that earn traffic. From Search Console and analytics, list every URL with clicks, impressions, or backlinks in the last 12 months. These rows get priority review.
  3. Map each old URL to one new URL. Closest equivalent page, not the homepage, not a category page unless nothing better exists.
  4. Mark intentional kills. Pages you're retiring on purpose should return 410 (gone) or redirect to a genuinely relevant parent. Document the decision either way.
  5. Check for collisions. Two old URLs pointing to the same new URL is fine. A new URL that's also in the old-URL column means you're about to build a chain.
  6. Spot-check the top 50. Open the highest-traffic rows manually. A formula error in row 3 of a spreadsheet replicates into 3,000 broken redirects.

For pattern-based moves — say /blog/2024/post-name becoming /blog/post-name — you can express the whole class as one server rule instead of thousands of spreadsheet rows. But still spot-check: pattern rules fail on edge cases like URLs with encoded characters or trailing-slash variants.


Where Should You Implement Redirects?

You've got three layers: server config, CMS, and CDN/edge. Each has a place.

Server config: nginx and Apache

Server-level redirects are fast and run before your application boots. Use them for big pattern-based moves and domain-level rules.

nginx — in your server block:

# Single page move
location = /old-page {
    return 301 /new-page;
}

# Pattern: drop the year from blog URLs
location ~ ^/blog/\d{4}/(.+)$ {
    return 301 /blog/$1;
}

# Whole-domain move (separate server block)
server {
    server_name old-domain.com;
    return 301 https://new-domain.com$request_uri;
}

return 301 is preferred over rewrite in nginx — it's faster and the intent is explicit.

Apache — in .htaccess or the vhost config:

# Single page move
Redirect 301 /old-page /new-page

# Pattern with mod_rewrite
RewriteEngine On
RewriteRule ^blog/\d{4}/(.+)$ /blog/$1 [R=301,L]

# Force HTTPS + non-www in one hop
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]

That last example matters: protocol and www-normalization should resolve in one redirect, not two stacked ones. Combine the conditions.

The downside of server config: every change needs a deploy or server access, and your content team can't touch it. That's fine for structural rules, painful for everyday content moves.

CMS-level redirect managers

Day-to-day redirects belong in the CMS, where editors can manage them without a deploy. This is the layer most teams underuse.

UnfoldCMS ships a built-in redirects manager for exactly this. Two details I'd call out because they remove the most common human errors:

  • Automatic slug history. Rename a post's slug and the old URL gets a redirect to the new one automatically. Nobody has to remember to add it — which is good, because in practice nobody remembers.
  • Optional expiry dates. Each redirect has an expires_at field. Leave it null for permanent 301s; set a date for temporary campaign redirects and they stop firing on schedule instead of living forever in a config file someone's afraid to touch.

Whatever CMS you run, check it covers those two cases. Slug renames are the most common source of accidental 404s on content sites, and stale "temporary" redirects are how /black-friday-2022 ends up redirecting somewhere weird four years later. If you're comparing platforms, our flat-file vs database CMS breakdown looks at how different architectures handle URL changes — flat-file systems often have no redirect layer at all, which pushes everything back onto server config.

Edge and CDN rules

Cloudflare Rules, CloudFront Functions, and similar products run redirects before requests ever reach your origin. They're the right tool for geographic routing, domain consolidation when you can't touch the origin server, and offloading huge redirect maps from a busy origin.

The risk is fragmentation. Once redirects live in three places — CDN, server config, CMS — debugging means checking all three, and a CDN rule can silently chain into a server rule. Keep one layer as the default home (the CMS, usually) and document anything that lives elsewhere.


Redirect Chains and Loops: Why More Than 2 Hops Hurts

A redirect chain is a redirect pointing at another redirect. Googlebot follows up to 10 hops before abandoning the URL, but every hop slows crawling, wastes crawl budget, and delays signal consolidation. Keep chains to one hop; never exceed two.

Chains build up innocently. The 2023 migration redirected /old/new. The 2025 redesign redirected /new/newer. Now /old takes two hops, and the backlinks pointing at it pass their signals through both.

The fix is flattening: when you add a redirect, update every existing redirect that pointed at the source so they all point directly at the final destination. After any migration, crawl your own redirect map — Screaming Frog's redirect chain report shows every multi-hop path.

Loops are the uglier sibling: /a/b/a. Browsers give up with ERR_TOO_MANY_REDIRECTS, users see an error page, and crawlers drop the URL entirely. Loops usually appear when a CMS rule and a server rule fight each other — say the CMS redirects to the trailing-slash version while nginx strips trailing slashes. One more reason to keep redirects in as few layers as possible.

The crawl budget angle is real for large sites. Every hop is an extra request Googlebot spends on plumbing instead of content. On a 200-page site nobody will notice. On a 50,000-URL site with chained legacy redirects, big sections can go stale in the index simply because the crawler spends its budget bouncing between redirects.


Temporary Redirects With Expiry Dates

Campaign URLs are the case nobody plans for. You point /promo at this year's landing page in March, the campaign ends in April, and the redirect lives on until someone trips over it in 2028.

The clean pattern: use a 302 (it's genuinely temporary), and give the redirect an expiry. In UnfoldCMS that's setting expires_at on the redirect — when the date passes, the redirect stops resolving and the URL returns to whatever it should be, no cleanup ticket required. Permanent redirects just leave the field null.

If your stack has no expiry concept, fake it with discipline: keep a "temporary" section in your redirect documentation with a review date, and put the review on a calendar. Boring, but it beats archaeology later.


How Do You Test Redirects Before and After Launch?

Test every redirect with curl -I, which shows the status code and Location header without downloading the page. Verify the code is right (301 vs 302), the destination is final (no chain), and HTTPS/non-www variants resolve in one hop.

curl -I https://example.com/old-page

HTTP/2 301
location: https://example.com/new-page

To follow the full chain and see every hop:

curl -sIL -o /dev/null -w "%{http_code} %{url_effective} -> " https://example.com/old-page

Things to check on every migration:

  1. Status code is the one you meant. A 302 where you wanted a 301 delays consolidation; a 301 where you wanted a 302 gets cached forever.
  2. One hop to a 200. If you see 301 → 301 → 200, flatten it.
  3. Variants behave. Test http://, https://, www., non-www, trailing slash, and no trailing slash. Each should reach the final URL in a single hop.
  4. The destination actually returns 200. Redirecting to a 404 is worse than no redirect.

For bulk testing, loop your redirect map through curl:

while IFS=, read -r old new; do
  result=$(curl -s -o /dev/null -w "%{http_code}" "$old")
  echo "$result $old"
done < redirect-map.csv

Run it before launch against staging, then again against production within an hour of going live.


Monitoring 404s After a Migration

Launch day isn't the finish line. For the first 4–8 weeks after a migration, watch three places:

  • Search Console → Pages → Not found (404). New 404s here are URLs Google knows about that your map missed. Add redirects for any with backlinks or past traffic.
  • Server access logs. Grep for 404 responses and sort by frequency. Logs catch what Search Console hasn't surfaced yet, including hits from other crawlers and old bookmarks.
  • Analytics landing-page report. A previously strong landing page flatlining usually means its redirect is wrong or missing.

Expect some turbulence — rankings commonly dip for a few weeks while Google reprocesses the site, then recover if the redirects are clean. What shouldn't happen is a sustained slide past week 6–8. If it does, audit the map again: the cause is almost always a batch of URLs redirecting somewhere irrelevant, or a chain you didn't flatten.

Keep your XML sitemap honest too — it should list only the new, final URLs, never the redirected ones. UnfoldCMS regenerates its sitemap from live content automatically, and the same source-of-truth idea extends to newer discovery files like llms.txt for AI search: every machine-readable surface should agree on which URLs are canonical.


FAQ

Do 301 redirects lose PageRank?

No. Google confirmed in 2016 that 3xx redirects no longer lose PageRank. What loses equity is redirecting to an irrelevant page (treated as a soft 404), chains of redirects, or removing the redirect before Google has consolidated signals — keep redirects live at least a year.

How long should I keep 301 redirects in place?

Google's official guidance is a minimum of one year, which is roughly how long consolidation can take on large sites. In practice, keep them as long as the old URL has backlinks. Server-level pattern rules cost nothing to leave forever.

Is a 302 redirect bad for SEO?

Not when the move is actually temporary — that's its job, and Google handles it fine. It's only a problem when a permanent move ships as a 302: the old URL can linger in the index and consolidation drags out. Google eventually treats long-lived 302s as 301s, but "eventually" is doing a lot of work in that sentence.

Should I redirect deleted pages to my homepage?

No. Bulk-redirecting deleted pages to the homepage is treated as a soft 404 and passes nothing. Redirect to the closest relevant page if one exists; otherwise return 410 so crawlers drop the URL cleanly.


Wrapping Up

Redirects are unglamorous infrastructure, and that's exactly why they fail — nobody owns them until traffic drops. Build the map first, pick the right status code, keep chains to one hop, test with curl, and watch the 404 reports for two months.

The CMS layer is where most of this either gets easy or gets ignored. UnfoldCMS handles the common cases by default: slug renames create their own redirects, the redirects manager supports expiry dates for campaign URLs, and the sitemap, JSON-LD, and llms.txt stay in sync with live content. It's a self-hosted Laravel CMS that runs on SQLite or MySQL — shared hosting included — with a one-time license. See how the SEO tooling fits together or try it on your own migration.


Sources: Google Search Central documentation on redirects and site moves; Gary Illyes' 2016 statements on 3xx PageRank; John Mueller's guidance on redirect duration via Google Search Central office hours. Server examples tested on nginx 1.24 and Apache 2.4.

Free & Open Source

Own your CMS. No subscriptions.

Unfold CMS is free to download and self-host. Built on Laravel + React, full source code included.

Share this post:

Discussion

Comments (0)

Leave a Comment

Please log in to leave a comment.

Don't have an account? Register here

No comments yet. Be the first to share your thoughts!

Keep Reading

Related Posts

Blog Comment Moderation: Spam, Trolls, and Sane Defaults

Blog Comment Moderation: Spam, Trolls, and Sane Defaults

A practical guide to blog comment moderation: choosing between pre-approval, post-publish, and hybrid models, layering honeypots and rate limits against spam, capping threads at 3 levels, and knowing when to turn comments off — with UnfoldCMS as the worked example.

Hamed Pakdaman
July 2, 2026 · 13 min
Back to all posts