Migrations without a redirect map destroy SEO equity. Redirect map is non-negotiable on every migration.
Pre-Migration Checklist
- Crawl old site with Screaming Frog or DataForSEO OnPage crawler
- Export all live URLs (200 status only)
- Identify URLs that will change slug or structure
- Build redirect map: old URL → new URL
- Identify orphan pages (no traffic, no backlinks) — keep, merge, or 301 to nearest parent
Redirect Map Format
| Old URL | New URL | Type | Notes | |---------|---------|------|-------| | /old-page/ | /new-page/ | 301 | Changed slug | | /category/services/ | /services/ | 301 | Removed category base | | /blog/post-title/ | /resources/post-title/ | 301 | Section rename | | /about-us/ | /about/ | 301 | Slug cleanup |
Implementing Redirects
Option 1 — Rank Math Redirections (< 100 redirects): Rank Math > Redirections > Add New > Source URL / Destination URL / Type: 301
Option 2 — .htaccess (Apache, unlimited scale):
Redirect 301 /old-page/ https://newsite.com/new-page/
Redirect 301 /old-category/old-post/ https://newsite.com/new-post/
Option 3 — Nginx:
rewrite ^/old-page/?$ /new-page/ permanent;
rewrite ^/old-category/(.*)$ /$1 permanent;
Option 4 — Bulk import via Redirection plugin:
wp redirection import --format=csv /path/to/redirects.csv
Post-Migration Validation
# Check redirect fires and follows chain
curl -I -L https://newsite.com/old-url/
# Verify 301 (not 302)
curl -o /dev/null -s -w "%{http_code}" https://newsite.com/old-url/
# Check for redirect loops (stop at 5)
curl -I --max-redirs 5 https://newsite.com/old-url/
Database Search-Replace
# Replace old domain in all DB tables
wp search-replace 'https://oldsite.com' 'https://newsite.com' \
--all-tables \
--report-changed-only
# Force rewrite flush after domain change
wp rewrite flush --hard