You're migrating a product page to a new URL structure, launching a rebrand, or consolidating duplicate content. Pick the wrong redirect status code, and you'll watch your organic rankings tank. In this post, we'll walk through exactly when to use Redirects: 301, 302, 307, 308—and why the difference between permanent and temporary matters far more than most developers realize.
Which Redirect — Compare CODE vs USE WHEN
HTTP redirect codes come in pairs: permanent (301, 308) and temporary (302, 307). The permanent ones preserve SEO equity; the temporary ones don't. But there's another dimension—whether the HTTP method (GET, POST, etc.) is preserved. Let me break down all four.
| Code | Type | Method Preserved | Use When |
|---|---|---|---|
| 301 | Permanent | No (POST → GET) | Moving a resource permanently; old URL will never exist again |
| 308 | Permanent | Yes (POST stays POST) | Moving a resource permanently but need to keep the HTTP method intact |
| 302 | Temporary | No (POST → GET) | Brief maintenance, A/B testing, or short-term URL changes |
| 307 | Temporary | Yes (POST stays POST) | Temporary redirect that must preserve the HTTP method |
In practice, as a developer building production systems, you'll use 301 or 308 for 95% of permanent moves. The method-preservation question only matters if your old endpoint accepted POST requests and the new one does too. For most content migrations—landing pages, product docs, blog posts—you're dealing with GET requests, so 301 is the standard choice.
Here's a typical nginx configuration:
server {
# Permanent redirect (301)
redirect_match ^/old-product-page$ https://example.com/new-product-page permanent;
# Temporary redirect (302)
redirect_match ^/seasonal-offer$ https://example.com/current-offer redirect;
}And in Next.js (which I use frequently), you'd handle it in next.config.js:
module.exports = {
async redirects() {
return [
{
source: '/old-product-page',
destination: '/new-product-page',
permanent: true, // 301
},
{
source: '/seasonal-offer',
destination: '/current-offer',
permanent: false, // 302
},
];
},
};The key insight: permanent: true outputs a 301 (or 308 if you specify the statusCode explicitly). permanent: false outputs a 302. Search engines treat these very differently.
Permanent Passes Signals — 301 and 308 Consolidate Ranking Signals to the New URL
This is where SEO and architecture intersect. When you use a 301 or 308 redirect, Google (and other search engines) transfer ranking signals—backlinks, domain authority, click-through rates—from the old URL to the new one. The search engine treats it as a true continuation of the resource, not a new resource.
Let's say you have a blog post at /blog/best-practices-2023 with 150 backlinks and ranking for "best practices in production." You move it to /blog/best-practices-2024 and set up a 301 redirect. Over time (usually 4–8 weeks), those ranking signals flow to the new URL. If you'd used a 302 instead, Google would treat it as temporary—the old URL stays in the index, the signals don't fully transfer, and you lose ranking power.
I've seen this happen in real migrations. During a rebrand at a fintech company, we moved dozens of API documentation pages. Using 301s meant we retained our organic visibility. A teammate at another company used 302s "temporarily" and forgot to update them. Six months later, their docs were barely ranking, and they had to rebuild everything from scratch.
The practical consequence: if you own a resource and are moving it permanently, 301 is not optional—it's how you protect your SEO investment.
Avoid Chains — Redirect Directly to the Final URL. Update Old Redirects after New Moves
Redirect chains are a silent killer. Imagine this scenario:
/old-url-v1redirects to/old-url-v2(301)/old-url-v2redirects to/current-url(301)/current-urlis the final resource
A crawler has to make three requests to reach the final page. Google officially supports up to three hops, but each redirect is a small penalty. More importantly, each redirect adds latency for users. In e-commerce or SaaS, that impacts conversion.
The fix is simple: when you move a URL, update any existing redirects that point to the old location. Instead of:
# Old redirect still in place
/v1/checkout → /v2/checkout (301)
# New migration happens
/v2/checkout → /v3/checkout (301)
# Now you have a chainReplace the original redirect:
# Updated to skip the middle step
/v1/checkout → /v3/checkout (301)Here's how I maintain this in production. In Next.js, I keep a central registry:
// redirects.json
{
"redirects": [
{
"from": "/old-product-page",
"to": "/products/new-name",
"permanent": true,
"lastUpdated": "2024-01-15"
}
]
}
// In next.config.js
const redirects = require('./redirects.json');
module.exports = {
async redirects() {
return redirects.redirects.map(r => ({
source: r.from,
destination: r.to,
permanent: r.permanent,
}));
},
};This makes auditing and updating redirects much easier. Every quarter, I scan for chains (a simple regex check) and consolidate them.
Server-Side Only — Meta Refresh and JavaScript Redirects Are Weak Signals
I've encountered production codebases that use meta refresh or JavaScript redirects for SEO-critical pages. This is a mistake.
A meta refresh tag looks like this:
And a JavaScript redirect:
Both are problematic. Search engine crawlers execute HTTP requests first, parse the HTML, then run JavaScript (though not all crawlers do this reliably). A meta refresh works, but it's slower than a server-side redirect and sends a weak signal to crawlers. JavaScript redirects are even worse—some crawlers may not execute the script, and the redirect intent is ambiguous.
The gold standard: always use HTTP status codes. A server-side 301 is instant, unambiguous, and passes full ranking signals. In every framework I work with—Next.js, NestJS, ASP.NET—I prioritize HTTP redirects.
The only exception: client-side navigation after page load (e.g., a button click redirecting to another page in your SPA). That's not an SEO redirect; it's user interaction.
Common Mistakes
- Using 302 for permanent moves: Developers often default to 302 because it sounds safer ("temporary, we can change it"). But if you know the move is permanent, 302 leaks SEO equity. Use 301.
- Forgetting to update redirects during migrations: If you move
/page-a→/page-band later move/page-b→/page-c, don't leave the first redirect in place. Update it to/page-a→/page-c. - Redirecting to a 404: I've seen this more than once—a redirect target that doesn't exist. Always test the redirect chain end-to-end. Use tools like Screaming Frog to audit all redirects quarterly.
- Redirecting HTTPS to HTTP: Modern browsers and crawlers penalize this. Always redirect to HTTPS.
- Setting long caches on redirect responses: If you redirect and set
Cache-Control: max-age=31536000, browsers will cache the redirect. If you change it later, users won't see the update for a year. Keep redirect cache times short (a few hours to a day).
Key Takeaways
- 301 and 308 are permanent; use them for final URL moves. They consolidate ranking signals and backlink equity to the new URL. 301 is the default for most cases.
- 302 and 307 are temporary; use them only for brief changes. They don't pass ranking signals, so search engines treat the old URL as the primary resource.
- Always redirect server-side. HTTP status codes are the standard. Meta refresh and JavaScript redirects are slow and send weak signals.
- Avoid redirect chains. Each hop adds latency and complexity. When you move a URL that's already a redirect target, update the original redirect to point directly to the new destination.
- Audit redirects regularly. Tools like Screaming Frog or built-in server logs help you spot chains, broken targets, and outdated redirects. A quarterly review prevents technical debt.






Comments
Loading comments…