Site Migrations
A migration is any change that alters URLs, rendering, or domain - redesigns, CMS/framework swaps, domain changes, HTTP→HTTPS, consolidating sites. It's the highest-stakes routine operation in SEO: done well, traffic dips slightly for a few weeks; done badly, years of accumulated equity evaporate in a deploy. The difference is process.
The iron rules#
- Every old URL gets a response plan. Redirect (301) to its closest equivalent, or deliberate 410. No mass 404s, no "the homepage will catch it."
- Redirect to equivalents, not the homepage. Blanket homepage redirects are treated as soft 404s - equity evaporates anyway.
- One change at a time when possible. Domain + design + platform + content all at once means when traffic drops, you can't isolate why.
- Measure before, so you can verify after.
Phase 1: Inventory (before anything else)#
Build the complete list of URLs that matter - from a full crawl, GSC (everything with impressions), analytics (everything with sessions), sitemap, and your backlink tool (everything with external links). Union these; the result is your migration universe. For each URL, record current traffic, rankings and linking domains - that's your baseline and your prioritization weight.
Phase 2: The redirect map#
A spreadsheet (or generated file) mapping every old URL to its new home:
old_url,new_url,type
/blog/2019/05/seo-tips,/guides/seo-basics,301
/products.php?id=42,/products/ergo-chair,301
/old-category/,/new-category/,301
/discontinued-thing,(410 gone),410Rules of thumb:
- Pattern-redirect where structure allows (
/blog/:year/:month/:slug → /guides/:slug), itemize the exceptions - No chains: old → new directly, including fixing existing old redirects to point at the final destination
- Page-to-page equivalence by intent: the new URL should satisfy the same query
In Next.js, bulk redirects live in config:
async redirects() {
return [
{ source: "/blog/:year/:month/:slug", destination: "/guides/:slug", permanent: true },
{ source: "/products.php", destination: "/products", permanent: true },
];
},(For very large maps, serve them from middleware/proxy or the edge config rather than thousands of static entries.)
Phase 3: Pre-launch on staging#
Audit the new site as if it were a stranger's (audit playbook) - crawl it, verify titles/canonicals/schema/render parity with production. Then test the redirect map against staging with a script: fetch every old URL, assert one-hop 301 to the mapped target.
Phase 4: Launch day#
□ robots.txt correct on production (no staging disallow!)
□ noindex absent from production templates
□ Redirect map live - spot-check top-100 old URLs
□ New sitemap submitted in GSC; old sitemap left up briefly
(it helps engines discover the redirects faster)
□ Domain change? → GSC "Change of address" tool
□ Canonicals point to new URLs (not old, not staging)
□ Analytics + GSC verified on the new property
□ Internal links updated to final URLs (not riding redirects)Phase 5: Monitor and stabilize#
Expect temporary flux (days to a few weeks) while engines reprocess. Watch daily at first:
- GSC Indexing on both properties: old URLs should drain as "redirected", new ones fill the index
- Crawl stats: a spike is normal (Google revisiting everything); sustained 404 spikes are your gaps - patch the redirect map as they surface
- Rankings/traffic by section vs. your Phase-1 baseline: section-level losses point at section-level mistakes (a template's canonical, a missed pattern)
- Server logs: Googlebot hitting old URLs and getting anything but a 301 = work
Keep redirects live for years (link equity flows through them as long as external links point at old URLs), and never recycle the baseline comparison away - +90 days against pre-migration numbers is the success criterion.
Next, the final guide: Analytics & Forecasting - reporting and predicting SEO as a professional.
