When you change a URL (renamed slugs, a new permalink structure, merged posts, a new domain), old links from Google, social media and other sites still point to the old address. A 301 redirect sends visitors and search engines to the new URL, and passes most of the old page’s ranking signals along. Here’s how to set redirects up in WordPress, and when to do it at the server level instead.

301, 302, 307, 308 and 410

Code Meaning Use for
301 Moved permanently URL changes, domain moves, HTTPS, merged content
302 Found (temporary) Short-term moves, A/B tests, maintenance
307 / 308 Temporary / permanent, preserving the method (POST stays POST) APIs and forms
410 Gone Content deliberately removed, with no replacement

For SEO-relevant moves, use 301 (or 308). See HTTP status codes.

What WordPress does automatically

  • Changed post slugs: WordPress remembers old slugs (_wp_old_slug) and redirects them. That’s helpful, but it can produce surprises when slugs are reused.
  • Canonical redirects: ?p=123 goes to the pretty permalink, www vs non-www follows the Site URL setting, and trailing slashes are normalised.

Option 1: a redirect plugin (easiest)

The free Redirection plugin (and the redirect managers in Yoast SEO Premium, Rank Math and others) lets you:

  • add 301s through the admin UI, with regex support;
  • log 404 errors, and create redirects from them;
  • import and export CSV lists, which is useful after migrations.

Plugin redirects run in PHP, after WordPress loads. That’s fine for dozens or hundreds of rules. For thousands of redirects, or very high traffic, server-level rules are more efficient.

Option 2: Nginx (fast, before PHP runs)

Single redirects in the site’s server block:

location = /old-page/ { return 301 /new-page/; }
location = /2019/05/old-post/ { return 301 /blog/new-post/; }

Patterns with regex:

# old date-based permalinks /2023/04/post-name/ → /post-name/
location ~ ^/\d{4}/\d{2}/([^/]+)/?$ { return 301 /$1/; }

Large lists, with a map (fast even with thousands of entries):

map $request_uri $redirect_to {
    include /etc/nginx/redirects.map;     # lines like: /old-url/ /new-url/;
}
server {
    …
    if ($redirect_to) { return 301 $redirect_to; }
}

Test and reload: sudo nginx -t && sudo systemctl reload nginx. See Nginx rewrite and return.

Option 3: Apache .htaccess

Above the WordPress block in .htaccess:

Redirect 301 /old-page/ https://example.com/new-page/
RedirectMatch 301 ^/\d{4}/\d{2}/(.+)$ https://example.com/$1

Or with mod_rewrite:

RewriteEngine On
RewriteRule ^old-category/(.*)$ /new-category/$1 [R=301,L]

See .htaccess guide and mod_rewrite.

Changing Settings → Permalinks (e.g. from /2023/04/post/ to /post/) changes every URL. WordPress handles some old formats, but not all. Add one pattern redirect (like the regex above), test sample URLs, and then update internal links:

wp search-replace 'https://example.com/2023/04/' 'https://example.com/' --all-tables --dry-run

See WordPress permalinks 404.

Moving to a new domain

  1. Set up the site on the new domain, and update URLs in the database (wp search-replace).
  2. On the old domain’s server block, redirect everything, preserving paths:
server {
    server_name old-example.com www.old-example.com;
    listen 80; listen 443 ssl;
    # ssl_certificate … (keep a valid certificate on the old domain!)
    return 301 https://new-example.com$request_uri;
}
  1. Keep the old domain registered, and the redirects running, for at least a year (ideally indefinitely).
  2. Use Google Search Console’s “Change of Address” tool.

See migrate WordPress to a VPS.

Avoid chains and loops

  • Chains: A → B → C. Each hop adds latency and dilutes signals. Update old rules to point straight to the final URL.
  • Loops: A → B → A (“too many redirects”). They’re often caused by conflicting HTTPS, www or plugin settings. See WordPress too many redirects.

Test

curl -sIL https://example.com/old-page/ | grep -iE '^HTTP|^location'

-L follows all hops. You should see one 301 and then 200. Crawlers like Screaming Frog find redirect chains and 404s across a whole site.

Quick reference

Need Best place
A few redirects, editor-managed Redirection plugin
Many redirects, or high traffic Nginx map / return 301
Apache hosting .htaccess Redirect / RewriteRule
Domain move Server-level catch-all 301 with $request_uri
Removed content 410 (or 301 to the closest relevant page)

Related: Nginx HTTPS redirect and WordPress on a VPS.

  • WordPress
  • SEO
  • Nginx