How to Redirect a URL in WordPress (3 Ways)

A redirect tells a browser — and a search engine — that the URL it just asked for now lives somewhere else. Set one up and anyone hitting the old address lands on the new page automatically, instead of on a 404. It’s one of the few maintenance jobs on a WordPress site that’s genuinely quick to do and genuinely costly to skip.
This guide covers when you actually need a redirect, which status code to use (they are not interchangeable), and three ways to set one up in WordPress — a plugin, your web server config, or PHP. We’ll finish with the mistakes that turn a good redirect into a slow-motion SEO problem, and how to test that the thing you just set up is really doing what you think.
When you need a redirect
Not every URL change needs one, but these four situations almost always do:
- You changed a post or page slug. The moment you edit a published permalink and hit update, the old URL is dead. Every existing link to it — from your own older posts, from other sites, from someone’s bookmarks — now points at a 404. WordPress does have some built-in guessing for old slugs, but it’s inconsistent and not something to rely on.
- You deleted or merged a post. If you’ve folded three thin posts into one comprehensive guide, all three old URLs should redirect to the new one. Deleting content without redirecting throws away every link and every bit of ranking those pages had earned.
- You moved domains or switched to HTTPS. A domain move means every URL on the old host needs to point at its equivalent on the new one. Same for
http://tohttps://, or the www / non-www decision — pick one canonical form and redirect the other. - You’re consolidating duplicate content. Two URLs serving nearly the same thing split their own signals and confuse crawlers. Pick the stronger one, redirect the weaker one into it. (A content audit is usually what surfaces these in the first place.)
The common thread: a redirect exists so that a URL somebody else controls a link to doesn’t stop working just because you reorganised things on your end.
Redirect types: which status code to use
The number matters. Search engines read it as a statement of intent, and picking the wrong one either loses you ranking signals or tells Google to keep the old URL indexed indefinitely.
| Code | Name | Meaning | Use it when |
|---|---|---|---|
301 |
Moved Permanently | This URL has moved for good. Search engines drop the old URL from the index over time and pass ranking signals to the new one. | Renamed slugs, merged posts, domain moves, HTTPS migrations — the default for 95% of cases. |
302 |
Found (temporary) | The content lives elsewhere for now, but the original URL is coming back. Google keeps indexing the original. | Genuinely temporary situations only — an A/B test, a seasonal landing page, a page down for maintenance. |
307 |
Temporary Redirect | The strict HTTP/1.1 version of a 302: the request method and body must be preserved (a POST stays a POST). |
Temporary redirects where the method matters — form submissions, APIs. Also what HSTS preloading issues internally. |
308 |
Permanent Redirect | Like a 301, but the method must be preserved too. Google treats it as equivalent to a 301 for ranking purposes. | Permanent moves where non-GET requests need to survive the hop. Rare on a content site. |
In practice: use 301 unless the move is genuinely temporary. The old myth that a 301 “leaks” some percentage of link equity has been retired — Google has said for years that PageRank is passed through 301s and 302s without loss. What a 302 does cost you is clarity: you’re telling search engines to keep the old URL as the canonical one, which is exactly wrong if the move is permanent.
If you leave a permanent move on a 302 for months, Google may eventually work out your real intent and treat it as permanent anyway — but you’ve spent that whole time with ambiguous signals for no reason. Set the correct code the first time.
Method 1: A redirect plugin (easiest)
For most people this is the right answer, and there’s no shame in it. A dedicated redirect plugin — Redirection is the long-standing free one, and most major SEO plugins include a redirects module in their premium tier — gives you a form: paste the old path, paste the new URL, choose the status code, save.
What you get beyond convenience:
- A 404 log. The plugin records URLs people (and crawlers) requested that didn’t exist. That log is a to-do list of redirects you didn’t know you needed — far more useful than guessing.
- Automatic slug redirects. Most of these plugins offer to create a 301 automatically whenever you change a published post’s permalink. Turn this on. It eliminates the single most common source of internal 404s.
- No server access needed. Works identically on shared hosting, managed WordPress, Apache, or nginx.
The honest trade-off is performance: plugin redirects are handled by PHP, so each one costs a WordPress bootstrap. For a few hundred redirects on a normal site that’s irrelevant. For tens of thousands, or for site-wide domain moves, do it at the server level instead.
Method 2: Server config (.htaccess or nginx)
Server-level redirects are the fastest possible option because they resolve before PHP ever loads. They’re also the least forgiving — a syntax error can take the whole site down, so back up the file before you touch it.
Apache (.htaccess)
Edit the .htaccess file in your WordPress root. Put your rules above the # BEGIN WordPress block, because WordPress rewrites that section and will wipe anything inside it.
The simplest form uses mod_alias:
Redirect 301 /old-post-slug/ https://example.com/new-post-slug/
Note that the first argument is a path and the second is a full URL. One gotcha: Redirect matches by prefix, so a rule for /blog also catches /blog-archive. Use RedirectMatch with an anchored pattern, or mod_rewrite, when you need precision:
RewriteRule ^old-post-slug/?$ /new-post-slug/ [R=301,L]
That belongs inside an <IfModule mod_rewrite.c> block with RewriteEngine On already set. The R=301 flag sets the status code; L stops rule processing there.
nginx
nginx doesn’t read .htaccess at all — rules go in your server block and require a reload (nginx -s reload) to take effect. The equivalents:
location = /old-post-slug/ { return 301 https://example.com/new-post-slug/; }
Or for a pattern with a capture: rewrite ^/blog/(.*)$ /articles/$1 permanent; — where permanent means 301 and redirect means 302.
If you’re on managed WordPress hosting you probably can’t edit nginx config directly; most hosts expose a redirects panel instead, which writes the same rules for you.
Method 3: PHP via functions.php
Sometimes a redirect depends on something only WordPress knows — the user’s role, whether a product is out of stock, a query parameter. That’s when you drop to PHP. Hook template_redirect, which fires after the query is resolved but before any output:
add_action( 'template_redirect', function () { if ( is_page( 'old-page' ) ) { wp_safe_redirect( home_url( '/new-page/' ), 301 ); exit; } } );
Three things to get right. Use wp_safe_redirect() rather than wp_redirect() when any part of the destination could come from user input — it restricts redirects to your own host. Always call exit; immediately after; without it, WordPress carries on rendering the page. And pass the status code explicitly, because wp_redirect() defaults to 302, which is not what you want for a permanent move.
Use this method sparingly. Code in functions.php runs on every single request, so a growing list of hand-written conditionals becomes a real tax on page generation and a maintenance burden nobody but you understands. If the rule is “old URL goes to new URL”, it belongs in a plugin or the server config. Reserve PHP for logic that genuinely needs to be conditional.
Common mistakes
Redirect chains and loops
A chain is A → B → C. Each hop adds latency for the visitor, and Google follows only a limited number of hops before giving up. Chains build up quietly over years of restructuring. The fix is to flatten them: point A directly at C and retire the middle rule. A loop (A → B → A) is worse — the browser gives up with an error and the page is simply unreachable. Loops usually come from two rules in different places, like an .htaccess rule fighting a plugin rule, so check both before adding a third.
Redirecting everything to the homepage
The lazy fix for a batch of 404s is a catch-all rule sending them all to /. Don’t. Google explicitly treats irrelevant mass redirects as soft 404s — the destination doesn’t answer the request, so it’s a dead end with extra steps — and users find it disorienting to click a specific link and land on a generic homepage. Redirect each URL to its closest genuine equivalent. If nothing equivalent exists, let it return a clean 404 (or 410 Gone if it’s deliberate and permanent). A real 404 is a perfectly valid answer.
Leaving your internal links pointing at the old URL
This is the one almost everyone skips. A redirect is a safety net for links you can’t change — other people’s sites, bookmarks, old emails. It isn’t a fix for links inside your own content, which you control and should simply update to the new URL, so readers and crawlers get there in one hop instead of two. Finding them all by hand is the tedious part; a linking tool with a bulk URL-change or broken-internal-link report does it in one pass — our own JnK Linkweave (disclosure: it’s ours, core is free) includes that report, and any tool that indexes your internal links will do the job. Either way, the same audit that finds broken links will surface the stale internal ones.
Not testing
A redirect you didn’t verify is a guess. Test every one, and test it in a way that shows you the actual status code.
How to test a redirect
Two reliable methods, both free.
- curl from a terminal. Run
curl -I https://example.com/old-url/. The-Ifetches headers only. You want to see the status line (HTTP/2 301) and alocation:header holding the new URL. To follow the whole chain and count the hops, usecurl -ILs https://example.com/old-url/— every 301 or 302 printed before the final200is one hop. More than one means you have a chain to flatten. - Browser dev tools. Open the Network tab before loading the URL, tick “Preserve log” (otherwise the redirect entry vanishes on navigation), then load the old address. The first row shows the original request with its 3xx status; click it to see the
Locationresponse header. Each subsequent row is another hop.
Test with your browser cache cleared or in a private window. Browsers cache 301s aggressively — that’s part of why they’re fast — which means a mistyped permanent redirect can appear to persist on your own machine long after you’ve fixed it on the server. If a redirect looks stuck, try a different browser or plain curl before assuming the rule is wrong.
Finally, check Google Search Console a couple of weeks after any large batch. The Pages report will show whether the old URLs are being dropped and the new ones indexed — the real confirmation that a permanent move landed properly.
Related reading
- Changing permalinks without losing traffic — the most common reason you suddenly need redirects
Frequently asked questions
What’s the difference between a 301 and a 302 redirect?
A 301 says the move is permanent: search engines drop the old URL from the index over time and pass ranking signals to the new one. A 302 says it’s temporary, so search engines keep indexing the original URL and treat the new location as a stopgap. Use a 301 for renamed slugs, merged posts, domain moves and HTTPS migrations, and reserve 302 for genuinely temporary situations like an A/B test or a page down for maintenance.
Can I redirect a URL in WordPress without a plugin?
Yes, in two ways. On Apache you can add a rule to your .htaccess file, such as Redirect 301 /old-slug/ https://example.com/new-slug/, placed above the # BEGIN WordPress block so WordPress doesn’t overwrite it; on nginx you add a return 301 or rewrite ... permanent; directive to your server block and reload. You can also redirect in PHP by hooking template_redirect and calling wp_safe_redirect() with a 301 status followed by exit;, but that code runs on every request, so keep it for cases that genuinely need conditional logic.
Is it bad to redirect old pages to my homepage?
Yes. Google treats irrelevant mass redirects to the homepage as soft 404s, because the destination doesn’t answer what the visitor asked for, and users find it disorienting to click a specific link and land on a generic page. Redirect each URL to its closest genuine equivalent instead, and if no equivalent exists, let the URL return a clean 404 — or a 410 if the removal is deliberate and permanent.