Every CMS migration that tanks organic traffic does so for the same handful of reasons. Broken redirects. Missing structured data. A sitemap that quietly halved. Open Graph images that defaulted to a generic logo. None of it is a Google secret. All of it is preventable with a checklist that gets run before, during and after cutover.
This is the version of that checklist we run on every migration at Roboto Studio. It's the same document our engineers and SEO leads work through together before, during and after cutover. Every item on it has, at some point, caught a real problem on a real client project. Use it on your own migration, or hand it to your current agency and ask which boxes they're ticking.
We've also built the whole thing as an interactive checklist on the CMS migration service page if you'd rather tick boxes than scroll. State persists in your browser, so you can come back to it across a multi-week migration without losing your place.
What this checklist covers
Twelve sections, in the order we run them:
- Baseline capture
- URL inventory and redirect map
- Sitemap audit
- JSON-LD parity
- OG image audit
- Robots.txt and llms.txt
- Internal-link audit
- Image migration
- Performance regression check
- Staging-to-production cutover
- The first 24 hours
- The 30-day monitoring window
If you only do five of these properly, do redirects, sitemaps, JSON-LD parity, the baseline capture, and the 30-day monitoring window. Those five catch the failures that actually move the needle on organic traffic.
1. Baseline capture
Before any data moves, snapshot the current site. You're going to need this to prove the migration was safe, and to diagnose anything that does regress.
- Full Ahrefs export of ranking keywords, referring domains, top organic pages, top organic queries and top backlinks.
- GSC Performance export for the last 12 months at page-level granularity. Clicks, impressions, CTR, average position.
- GSC Coverage export. Indexed pages, excluded pages, valid-with-warnings, errors.
- Sitemap snapshot: download the live XML sitemap to disk so you can diff it post-launch.
- Internal-link graph: run Screaming Frog over the site and export the crawl.
- Page-speed baseline: pull a PageSpeed Insights and Lighthouse run for the top 10 templates.
- Schema inventory: open three to five pages of each template type in the Rich Results Test and log every JSON-LD type the old site emits.
This is one to two days of work that nobody enjoys. The teams that skip it are the teams that can't tell, six weeks post-launch, whether a 14% traffic drop is migration regression or normal seasonality.
2. URL inventory and redirect map
This is the single highest-leverage step on the list. Get it wrong and you surrender months of compounding link equity to soft 404s.
- Pull every URL with at least one organic click in the last 12 months from GSC.
- Pull every URL with at least one referring domain from Ahrefs.
- Pull every URL in the current XML sitemap.
- Deduplicate. This is your redirect-map source list.
- For each URL, define the closest equivalent on the new site. Categories, tag archives, author pages, paginated lists, the long tail of orphaned posts: nothing gets surrendered to a soft 404. If there's genuinely no equivalent, redirect to the parent category, not the homepage.
- Sign off the map in a spreadsheet before any code ships. Engineering, SEO and content all sign the same row.
- Implement as proper 301s at the edge (Vercel middleware, Cloudflare rules, or framework-level redirects). Avoid client-side redirects, JavaScript redirects, or 302s. Google treats 302s as temporary and won't transfer link equity.
If your CMS migration is moving 4,000 pages and your redirect map has 50 entries, you have a problem.
3. Sitemap audit
The new sitemap should have at least as many URLs as the old one once you account for legitimately deprecated pages. Check before launch and again 48 hours after.
- Build the new XML sitemap as part of the launch, not as a follow-up ticket.
- Diff old vs new. Investigate every URL that's in the old sitemap but not the new one. Either it should be in the new sitemap, or it should be 301'd to a URL that is.
- Cap individual sitemaps at 50,000 URLs. Use a sitemap index for anything larger.
- Submit the new sitemap to GSC on cutover day. Watch the indexing count climb over the following week.
- Remove the old sitemap from GSC once the new one is fully indexed.
4. JSON-LD parity
Structured data drives rich results in the SERP. Lose it and you lose star ratings, FAQ accordions, breadcrumb trails and product cards: every part of the snippet that makes your listing more clickable than the one above it.
- Catalogue every JSON-LD type on the old site from your schema inventory in step 1.
- Rebuild each type on the new site. Article, NewsArticle, FAQPage, BreadcrumbList, Product, Organization, VideoObject, Recipe, Review: whichever ones the old site had.
- Validate each template on the new site through the Rich Results Test before launch.
- Re-validate via GSC's Enhancements reports 72 hours after launch. Rich results take days to recrawl, not minutes.
A common regression: the old WordPress site had FAQPage schema via a plugin. The new Next.js site shipped without it. The FAQ accordions disappeared from the SERP and CTR on those pages dropped 20%.
5. OG image audit
Open Graph is the easiest thing to miss because nothing breaks visibly until someone shares a link.
- For every URL on the redirect map, confirm an OG image renders on the new site.
- Confirm OG titles and descriptions are populated, not falling back to a generic site default.
- Confirm Twitter Card metadata is set (twitter:card, twitter:image).
- Spot-check 10 URLs through the Twitter / X Card Validator, Facebook Sharing Debugger and LinkedIn Post Inspector. Force a re-scrape on each one so the cache busts.
- Confirm dynamic OG image generation works for blog posts, case studies and product pages. We use Vercel's @vercel/og runtime; whatever you use, test it on real production URLs, not localhost.
6. Robots.txt and llms.txt
- Confirm the new robots.txt allows crawling of every section that should be indexed. The most common regression: a staging environment's
Disallow: /makes it to production. - Confirm the sitemap URL is referenced from robots.txt.
- Confirm any intentional disallows from the old robots.txt are preserved on the new one. Don't accidentally start indexing your
/wp-admin/equivalent. - Add an llms.txt file at the root if you want AI crawlers to find your highest-signal content. Document your AI crawling preferences explicitly: GPTBot, ClaudeBot, PerplexityBot and CCBot all read robots.txt; llms.txt is the emerging convention for AEO discoverability.
7. Internal-link audit
Internal links carry roughly half the SEO value on most content sites. If they break during migration, page authority redistributes in ways you didn't plan for.
- Crawl the new site with Screaming Frog. Diff the internal-link graph against the baseline from step 1.
- Investigate every page that lost more than 50% of its inbound internal links.
- Fix any internal links that still point to old URLs. They'll hit the 301 and work, but each one wastes a redirect hop and ages badly.
- Confirm the navigation, footer and contextual link blocks all carry over.
8. Image migration
- Move images to your new asset host (Vercel Blob, Cloudinary, Bunny CDN). Don't keep serving from the old WordPress uploads directory after cutover.
- Preserve alt text. The most common regression: a CSV export drops the alt-text column.
- Preserve filenames where possible. Image search ranks partly on filename and surrounding text; renaming
red-shoes-product.jpgtoimage-2347.jpgresets that signal. - Use modern formats. AVIF and WebP cut file sizes by 30 to 50% over JPEG with no visible quality loss.
- Configure responsive sizes. Next.js'
<Image>component handles this; on other stacks you may need to generate the responsive variants explicitly.
9. Performance regression check
- Run Lighthouse against the top 10 templates on staging. Compare to the baseline from step 1.
- Watch for Core Web Vitals regressions: LCP, INP, CLS. Cache Components and ISR in Next.js make this much easier; on other stacks, lean on CDN caching and edge rendering.
- Test on real devices and throttled connections, not just your dev machine. Most regressions only surface on mid-range mobile.
- Confirm fonts are preloaded, not loaded asynchronously. A delayed web font is the most common cause of CLS spikes post-migration.
10. Staging-to-production cutover
- Launch behind a feature flag, staging subdomain, or DNS-controlled rollout. Don't flip everything at once.
- Have the redirect map already deployed at the edge when DNS flips. The first request to an old URL should 301 cleanly.
- Submit the new sitemap to GSC at the same moment as the DNS flip. Don't wait until the next morning.
- Keep the old site warm for 72 hours after cutover. If something is catastrophically wrong, you want the rollback path to be a DNS change, not a re-deploy.
- Notify any aggregators, syndicators or partners whose feeds point at the old URLs.
11. The first 24 hours
- Monitor GSC Coverage hourly for the first six hours. Watch for sudden spikes in 404s, redirect errors or excluded URLs.
- Check Real User Monitoring (Vercel Analytics, Speedcurve, SpeedVitals) for Core Web Vitals on real traffic, not synthetic tests.
- Spot-check 30 redirects manually. The map looked right in the spreadsheet; confirm it behaves right in production.
- Re-validate top-template rich results in GSC. Don't wait for Google to surface the regression.
- Watch your error tracking (Sentry, BugSnag) for any new client-side errors that only manifest in production data.
12. The 30-day monitoring window
The first 30 days post-launch are where rankings actually settle. Don't invoice and walk away.
- Daily for the first week: GSC Coverage, top organic page clicks, top organic query positions.
- Weekly for the first month: Ahrefs ranking diff, referring-domain count, organic-traffic trend vs the equivalent pre-launch week, schema validity in GSC Enhancements.
- Investigate any page that loses more than 30% of its organic traffic week-over-week. The fix is almost always one of: missing redirect, missing schema, missing internal link, missing OG image.
- Submit any newly identified ranking pages for re-indexing through the URL Inspection tool.
By day 30, organic traffic should be at parity with pre-launch or growing. If it's down materially, you have a regression to investigate, not seasonality to explain away.
Optional: GEO and AEO monitoring loop
Everything above protects your organic search position. Increasingly, that's only half the story. Brand visibility inside ChatGPT, Perplexity, Claude and AI Overviews moves on different signals: structured answer-first content, llms.txt, schema enrichment beyond classic rich results, and citation tracking in the LLMs themselves.
Migration cutover is the right moment to re-baseline AI-surface visibility, because the same content reshuffle that affects Google can also affect what LLMs cite. We run this as a parallel loop on every migration where AI traffic matters:
- Publish
llms.txtat the root with the highest-signal pages surfaced explicitly. - Set an AI crawler policy in
robots.txt. GPTBot, ClaudeBot, PerplexityBot, CCBot and Google-Extended are the ones that matter today. Decide allow vs disallow per crawler, not blanket. - Baseline AI Overview presence for your top 50 queries before cutover. Profound, Otterly, Athena or even manual sampling. Record citation share, position and the URL the AI engine actually links to.
- Track citations weekly in ChatGPT, Perplexity, Claude and Gemini for branded and category queries. Watch for fidelity drift and lost mentions.
- Enrich schema beyond what classic rich results need. FAQPage, HowTo, Article body, Dataset and Quotation schema all feed AI extraction.
- Rewrite top-traffic templates answer-first. A TL;DR, definition or direct answer inside the first 60 words means an LLM can extract without scrolling.
- Expose markdown or plain-text alternates for AI agents. Content negotiation on
Accept: text/markdownor.mdmirrors of the highest-value URLs. - Schedule a 30-day GEO/AEO review post-launch. Compare AI-surface presence pre vs post at the page level, not just at the brand level.
This isn't a one-off task you tick during a migration. It's an ongoing monitoring loop that runs monthly. If you'd rather hand it off than build it in-house, we run it as a service: generative engine optimisation for the parallel-search visibility programme and answer engine optimisation for the deeper structured-content work.
When this checklist isn't enough
Two situations need more than a checklist:
International or multi-language migrations. Hreflang implementation, regional sitemaps and language-specific content variants add a layer of complexity this list doesn't cover. We treat these as separate engagements with their own pre-launch playbook.
Headless commerce migrations. Product pages, variants, collection URLs and stock-status structured data have their own failure modes. The headless Shopify and Sanity work we ship has a parallel checklist focused on commerce-specific schema and category-page parity.
If either of those applies to your migration, talk to us on a scoping call before launch. The checklist gets you 80% of the way; the last 20% is where engagement-specific risk lives.
Use it on your own migration
This checklist is openly published because every migration that gets shipped properly is one fewer migration that has to be recovered later. Save it. Send it to your team. Hand it to the agency you're working with and ask which items they're already covering. If half are missing from their process, that's worth a conversation before contracts get signed.
If you'd rather not run it yourself, we run CMS migrations for teams replatforming off WordPress, Webflow, HubSpot CMS, Drupal, Sitecore and Framer onto Sanity or Contentful. Every engagement closes the loop on the 30-day monitoring window, so we see the rankings settle and the regressions surface, not just the launch.

