What is 301 Redirect?
A 301 redirect is a permanent HTTP redirect that transfers a URL's ranking signals to a new destination.
What is a 301 Redirect?
A 301 redirect is an HTTP response status code that tells clients a resource has permanently moved to a new URL. Defined way back in HTTP/1.0 (RFC 1945, 1996) and carried through every spec since, the 301 signals browsers and search crawlers to update their records. Google confirmed in 2016 that 301 redirects pass full PageRank — ending years of SEO anxiety about "link equity loss." When a crawler hits a 301, it indexes the destination URL and eventually drops the old one from the index. We use 301s on virtually every site migration, domain consolidation, and slug restructure we ship. Common scenario: you're rebranding from olddomain.com to newdomain.com and need Google to transfer all those accumulated ranking signals to the new domain without starting from zero.
How it works
When a client (browser, Googlebot, whatever) requests a URL, the server responds with a 301 Moved Permanently status and a Location header pointing to the new URL. The client then makes a second request to that new URL.
Here's the raw HTTP exchange:
GET /old-page HTTP/1.1
Host: example.com
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page
In a Next.js project (App Router, Next.js 14+), you'd configure this in next.config.js:
module.exports = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true, // emits 308 by default; use statusCode: 301 if needed
},
];
},
};
Note: Next.js uses 308 (the modern equivalent that preserves HTTP method) when you set permanent: true. If you specifically need a 301 (e.g., for legacy bot compatibility), pass statusCode: 301 instead of permanent.
For Nginx, the config is straightforward:
server {
rewrite ^/old-page$ /new-page permanent;
}
Browsers cache 301s aggressively. Chrome caches them indefinitely in its local redirect cache. This matters because a misconfigured 301 can be painful to reverse — users who already visited will keep getting sent to the wrong place even after you remove the server rule.
When to use it
Use a 301 redirect when the move is permanent and you want search engines to transfer ranking signals.
Use a 301 when:
- Migrating to a new domain
- Consolidating HTTP to HTTPS or www to non-www
- Changing URL slugs permanently (after a content restructure, say)
- Merging duplicate pages into a canonical URL
- Sunsetting old product pages that have inbound links
Don't use a 301 when:
- The move is temporary (use a 302 or 307 instead)
- You're A/B testing URLs (302 keeps the original indexed)
- You're redirecting based on geolocation or device — that's cloaking-adjacent and better handled by
Varyheaders or client-side logic - You can fix the canonical tag instead — a 301 adds a round-trip; if both URLs should exist,
rel=canonicalis cheaper
We've shipped redirect maps with 10,000+ rules on site migrations. The key is testing every rule before launch and monitoring crawl logs for 2-4 weeks after.
301 Redirect vs alternatives
| Code | Name | Permanent? | Passes link equity? | Method preserved? | Best for |
|---|---|---|---|---|---|
| 301 | Moved Permanently | Yes | Yes | No (may change POST→GET) | Domain migrations, slug changes |
| 302 | Found | No | Partially (Google treats long-lived 302s as 301s) | No | Temporary moves, A/B tests |
| 307 | Temporary Redirect | No | Partially | Yes | API temporary redirects |
| 308 | Permanent Redirect | Yes | Yes | Yes | Modern apps (Next.js default) |
| Meta refresh | — | No | Minimal | N/A | Avoid for SEO |
The 308 is effectively the modern 301. The only difference is 308 guarantees the HTTP method stays the same (a POST stays a POST). For GET-based page URLs, 301 and 308 are functionally identical. Our preferred approach: use 308 via Next.js permanent: true for new projects, and 301 explicitly when dealing with legacy crawlers or edge cases.
Real-world example
We migrated a SaaS client's marketing site from a subdomain (marketing.app.com) to the root domain (app.com). The redirect map contained 847 rules covering blog posts, landing pages, and PDF assets. We implemented these as 301s in Cloudflare Workers (sub-millisecond response time, no origin hit). Within 6 weeks, Google Search Console showed 94% of indexed URLs had transitioned to the new domain. Organic traffic dipped ~12% in week one, recovered fully by week three, and grew 8% by week six — partly because the root domain had stronger domain authority. The critical step was validating every redirect with a crawl tool (we used Screaming Frog) before flipping DNS, and keeping the old subdomain's redirects live for 12+ months.