{"slug":"wordpress-migration-redirect-map","title":"WordPress Migration and Redirect Map","tags":["migration","redirects","301","seo","wp-cli"],"agent_summary":"Complete WordPress migration SOP: pre-migration crawl, redirect map format, .htaccess and Rank Math redirect implementation, post-migration validation with curl, and database search-replace.","trigger_phrases":["wordpress migration","redirect map wordpress","301 redirects migration","wp search-replace domain","migrate wordpress site","htaccess redirects","wordpress seo migration"],"runnable":true,"markdown":"\nMigrations without a redirect map destroy SEO equity. Redirect map is non-negotiable on every migration.\n\n## Pre-Migration Checklist\n\n1. Crawl old site with Screaming Frog or DataForSEO OnPage crawler\n2. Export all live URLs (200 status only)\n3. Identify URLs that will change slug or structure\n4. Build redirect map: old URL → new URL\n5. Identify orphan pages (no traffic, no backlinks) — keep, merge, or 301 to nearest parent\n\n## Redirect Map Format\n\n| Old URL | New URL | Type | Notes |\n|---------|---------|------|-------|\n| /old-page/ | /new-page/ | 301 | Changed slug |\n| /category/services/ | /services/ | 301 | Removed category base |\n| /blog/post-title/ | /resources/post-title/ | 301 | Section rename |\n| /about-us/ | /about/ | 301 | Slug cleanup |\n\n## Implementing Redirects\n\n**Option 1 — Rank Math Redirections (< 100 redirects):**\nRank Math > Redirections > Add New > Source URL / Destination URL / Type: 301\n\n**Option 2 — .htaccess (Apache, unlimited scale):**\n\n```apache\nRedirect 301 /old-page/ https://newsite.com/new-page/\nRedirect 301 /old-category/old-post/ https://newsite.com/new-post/\n```\n\n**Option 3 — Nginx:**\n\n```nginx\nrewrite ^/old-page/?$ /new-page/ permanent;\nrewrite ^/old-category/(.*)$ /$1 permanent;\n```\n\n**Option 4 — Bulk import via Redirection plugin:**\n\n```bash\nwp redirection import --format=csv /path/to/redirects.csv\n```\n\n## Post-Migration Validation\n\n```bash\n# Check redirect fires and follows chain\ncurl -I -L https://newsite.com/old-url/\n\n# Verify 301 (not 302)\ncurl -o /dev/null -s -w \"%{http_code}\" https://newsite.com/old-url/\n\n# Check for redirect loops (stop at 5)\ncurl -I --max-redirs 5 https://newsite.com/old-url/\n```\n\n## Database Search-Replace\n\n```bash\n# Replace old domain in all DB tables\nwp search-replace 'https://oldsite.com' 'https://newsite.com' \\\n  --all-tables \\\n  --report-changed-only\n\n# Force rewrite flush after domain change\nwp rewrite flush --hard\n```\n","html":"<p>Migrations without a redirect map destroy SEO equity. Redirect map is non-negotiable on every migration.</p>\n<h2>Pre-Migration Checklist</h2>\n<ol>\n<li>Crawl old site with Screaming Frog or DataForSEO OnPage crawler</li>\n<li>Export all live URLs (200 status only)</li>\n<li>Identify URLs that will change slug or structure</li>\n<li>Build redirect map: old URL → new URL</li>\n<li>Identify orphan pages (no traffic, no backlinks) — keep, merge, or 301 to nearest parent</li>\n</ol>\n<h2>Redirect Map Format</h2>\n<p>| Old URL | New URL | Type | Notes |\n|---------|---------|------|-------|\n| /old-page/ | /new-page/ | 301 | Changed slug |\n| /category/services/ | /services/ | 301 | Removed category base |\n| /blog/post-title/ | /resources/post-title/ | 301 | Section rename |\n| /about-us/ | /about/ | 301 | Slug cleanup |</p>\n<h2>Implementing Redirects</h2>\n<p><strong>Option 1 — Rank Math Redirections (&#x3C; 100 redirects):</strong>\nRank Math > Redirections > Add New > Source URL / Destination URL / Type: 301</p>\n<p><strong>Option 2 — .htaccess (Apache, unlimited scale):</strong></p>\n<pre><code class=\"language-apache\">Redirect 301 /old-page/ https://newsite.com/new-page/\nRedirect 301 /old-category/old-post/ https://newsite.com/new-post/\n</code></pre>\n<p><strong>Option 3 — Nginx:</strong></p>\n<pre><code class=\"language-nginx\">rewrite ^/old-page/?$ /new-page/ permanent;\nrewrite ^/old-category/(.*)$ /$1 permanent;\n</code></pre>\n<p><strong>Option 4 — Bulk import via Redirection plugin:</strong></p>\n<pre><code class=\"language-bash\">wp redirection import --format=csv /path/to/redirects.csv\n</code></pre>\n<h2>Post-Migration Validation</h2>\n<pre><code class=\"language-bash\"># Check redirect fires and follows chain\ncurl -I -L https://newsite.com/old-url/\n\n# Verify 301 (not 302)\ncurl -o /dev/null -s -w \"%{http_code}\" https://newsite.com/old-url/\n\n# Check for redirect loops (stop at 5)\ncurl -I --max-redirs 5 https://newsite.com/old-url/\n</code></pre>\n<h2>Database Search-Replace</h2>\n<pre><code class=\"language-bash\"># Replace old domain in all DB tables\nwp search-replace 'https://oldsite.com' 'https://newsite.com' \\\n  --all-tables \\\n  --report-changed-only\n\n# Force rewrite flush after domain change\nwp rewrite flush --hard\n</code></pre>\n"}