The WordPress migration checklist: content, URLs, redirects, SEO
The checklist we work through on every WordPress migration: the URL inventory, getting content out, the redirect map, metadata parity, and the first month in Search Console.
Updated 21 August 2026
Every WordPress site we've been handed for migration had more URLs than its owner thought. The record so far is a site with 38 pages in the menu and a bit over 1,900 URLs in Google's index. The other 1,860-odd were tag archives, date archives, paginated category pages, attachment pages, RSS feeds, and a run of /?p=123 addresses left over from before someone turned on pretty permalinks in 2014. Nobody chose those URLs. WordPress generated them, Google indexed them, and a handful had inbound links worth real money.
That gap, between the site you think you have and the site Google has, is where migrations go wrong. The new build is rarely the problem. WordPress still runs about 43% of all websites, so this checklist gets a regular workout at our end, and the failures repeat with almost boring consistency. Here's the list we actually work through, in order. The case for leaving WordPress at all is a separate piece; this one assumes you've decided and want to arrive with your rankings intact.
Inventory before anything else
You can't redirect what you never listed. Before a single line of the new site is built, we produce three lists and merge them.
First, a full crawl of the live site with something like Screaming Frog, which finds every URL the site links to internally, including the archive pages and attachment URLs nobody remembers creating. Second, a Search Console export: top pages by clicks for the last twelve months, plus the full indexed-page list. This is the list of URLs that are actually earning, and it's the one you'll defend. Third, the existing sitemap.xml, which tells you what the old site believes about itself. The three lists never match. The differences are the interesting part.
Google's own guide to a site move with URL changes says roughly the same thing in more formal language, and it's worth reading in full because it's short and most of the horror stories come from skipping its first section. Do the Search Console export even if you do nothing else today. It takes ten minutes and it's the only before-and-after evidence you'll ever have.
Getting the content out
WordPress gives you two doors. The built-in export tool produces a WXR file, which is XML holding your posts, pages, comments, categories and custom fields. The REST API serves the same content as paginated JSON at /wp-json/wp/v2/posts, with the rendered HTML included.
We use the REST API for almost every port now, for one reason: rendering. The WXR file stores content as it was typed, so a gallery is [gallery ids="4,12,31"], a shortcode that means nothing outside WordPress. The API gives you the HTML that shortcode became. If the site is ten years old and three page builders deep, that difference is weeks of work.
Now the stuff people forget, which is most of the job. Media: the export references your images but does not contain them; /wp-content/uploads has to be pulled down separately, and it's usually gigabytes. Comments: they come along in the export, but your new stack probably has nowhere to put them, and "we're dropping the comments" is a decision someone should make out loud. Form entries: Gravity Forms and Contact Form 7 submissions live in their own database tables and are in no export at all. Embeds: WordPress silently expands a bare YouTube URL into a player; on the new platform that same line is just a link, so every embed needs finding. And metadata from Yoast or Rank Math sits in wp_postmeta, not in your content, which matters in a minute.
The redirect map is the highest-stakes artefact
One document decides whether the migration is invisible or a disaster: the spreadsheet with every old URL in column A and its new home in column B. We've written about who should own that map and why in the context of redesigns generally. The WordPress-specific part is that the old URL list is stranger than you expect.
WordPress has had several permalink structures over its life, and old sites tend to carry fossils from each: /?p=123 query strings, date-based /2016/03/slug/ paths, /category/services/slug/ prefixes. WordPress itself redirects the old forms to the current one behind the scenes. The day you leave, that courtesy ends, unless your map carries it forward.
Then the generated URLs. Category and tag archives, author pages, /page/2/ pagination, attachment pages, and the feed URLs at /feed/ and friends, which real humans and real software still subscribe to. Not all of these deserve a mapped destination. Archives can often go to the nearest topic page, and some URL classes have honestly earned a 410. But each class gets a deliberate decision, written down, not a default 404.
The mechanism is a 301, a permanent redirect, and Google's redirect documentation is clear that this is what passes signals to the new URL. Google suggests keeping redirects at least a year. We never remove them. There is no prize for tidiness here.
Metadata has to make the trip too
The content port moves your words. It does not move your titles and meta descriptions, because on most WordPress sites those live in SEO-plugin tables, separate from the content. If the new site regenerates titles from a template, you've just rewritten the snippet Google shows for every page at once. Pull the plugin data and carry it across.
Same for canonicals, which tell Google which URL is the real one when several resolve; for structured data, where a LocalBusiness or Article block that took years to earn rich results can vanish in a rebuild without anyone noticing for months; and for Open Graph images, which are what your pages look like when shared. None of these break the site when they're missing. They just quietly stop earning.
Test before you touch DNS
With the new site on a staging URL, crawl it the same way you crawled the old one. Then run the diff that matters: take the full old-URL inventory and request every single one against the new configuration. Each should land on a 200 within one hop. This is a script, not an afternoon of clicking, and it catches the mapping errors while they're free to fix.
Check the staging site carries a noindex and the production build doesn't. Google's documentation on blocking indexing covers the mechanics; the two classic accidents are the staging domain getting indexed and competing with you, and the noindex tag shipping to production inside the launch build. We've seen both. The second one is worse.
Cutover, and the month after
Drop the DNS TTL a day or two before so the switch propagates fast, then cut over at a quiet hour for your traffic. Same day: submit the new sitemap in Search Console. Google's site-move guide also suggests temporarily keeping a sitemap of the old URLs live, which sounds wrong and works, because it prompts Google to recrawl the old addresses and discover the redirects sooner.
Then watch Search Console for a month. The pages report will show a swell of "page with redirect" entries, which is the system working. What you're hunting is 404s on URLs from your inventory, and any click-collapse concentrated in a few previously strong pages, which nearly always means a mapping gap rather than anything mysterious. A general wobble for two or three weeks is normal recrawl noise. A launch-day drop that never recovers is not.
The failure modes we keep meeting
Trailing slashes: the map says /services/plumbing/, the new server serves /services/plumbing, and depending on configuration every redirect now chains or misses. Pick one form and enforce it everywhere.
Hotlinked images: your old posts, other people's sites and years of sent emails all reference absolute /wp-content/uploads/... URLs. If those paths die, images break in places you can't even see. Map the uploads directory wholesale.
Feeds: /feed/ returns 404 and every subscriber's reader goes dark without a sound. Redirect it to the new feed if you have one.
And the staging leak, covered above, which is common enough that we check for it on every audit of a recently rebuilt site.
Where AI tooling changes the maths
The honest reason migrations used to be quoted in weeks is that most of the work is careful drudgery: 1,900 rows of redirect mapping, hundreds of posts to port and re-check, metadata to reconcile. This is exactly the work AI coding agents are good at. We hand Claude Code the crawl export and the new route list and it drafts the redirect map, flags the URLs with no obvious destination for a human call, and writes the redirect config in whatever form the new host wants. It ports posts from the REST API into MDX and produces a diff we can actually review, image paths and metadata included.
That's the real difference between the platforms. On the new stack, the entire site is typed files in a git repository, so an agent can read it, change it, and submit the change for review, and a type error catches its mistakes at build time. A WordPress site is state spread across a MySQL database, plugin option tables and a themed PHP runtime, and there's no safe way to let an agent loose in that. No diff, no review, no undo.
Keep expectations honest: the agent grinds through the mapping, but it can't decide which of your pages deserve to live. That call is still editorial, and it's still yours. What changes is the bill. The tedious half of a migration, the part that made the old quotes eye-watering, now takes days rather than weeks. The rebuilds themselves are cheaper too, which we've covered in the destination guides, like WordPress to Astro.
If you'd rather hand it over
This checklist is the process we run on every migration: inventory, content import, the redirect map, the redesign, and Cloudflare hosting on the other side, with Search Console watched for the month after cutover. If you want to know what a migration would look like for your site, start with a free audit and we'll tell you what's actually earning, what the URL inventory looks like, and whether moving is even worth it yet. Sometimes it isn't, and we'd rather say so before anyone signs anything. Otherwise, tell us about the project.