WordPress to headless CMS: a migration checklist
TL;DR
A WordPress-to-headless migration runs in seven steps (audit, export, model, import, rebuild, redirect, QA), typically 4–8 weeks, and usually cuts ongoing hosting and maintenance cost by 25–40%.
A WordPress-to-headless migration is one audit up front, then six steps (export, map & model, import, rebuild, redirects, and QA), and for a typical content site it takes 4–8 weeks. Moving the posts is the easy part. The hard part is untangling what your plugins were doing, mapping that to a clean content model, and not breaking a single URL on the way out. This checklist walks the whole thing, then shows where an API- and CLI-driven CMS makes the import step boring instead of painful.
Copy the checklist, work top to bottom, and skip nothing in the audit. That's where migrations go sideways.
The checklist (copy this)
Audit (do this before the six steps)
- [ ] Inventory every post type (posts, pages, custom post types, taxonomies)
- [ ] List every active plugin and what it actually does (not what it's named)
- [ ] Classify each plugin: built-in feature / moves to frontend / real rework
- [ ] Count media assets and total size; find where they're served from
- [ ] Export the current URL map (every indexed URL, from sitemap + GSC)
- [ ] Record locales, language plugins, and how translations are stored
1. Export
- [ ] Pull content via WXR export and/or the WordPress REST API
- [ ] Normalize into a structured intermediate (JSON/CSV) you can re-run
- [ ] Convert post HTML to your target format; strip shortcodes/plugin markup
2. Map & model
- [ ] Map each post type to a content type/collection in the new CMS
- [ ] Decide field-by-field: which ACF/meta fields survive, merge, or die
- [ ] Model relationships (categories, authors, related posts) as references
- [ ] Design locale handling (one type, per-locale entries, not a type per language)
3. Import
- [ ] Script the import against the CMS API or CLI (repeatable, not manual)
- [ ] Import media first, capture new URLs, then rewrite body references
- [ ] Dry-run on a subset, diff the output, then run the full load
4. Rebuild
- [ ] Wire the frontend to fetch content over the API at build time
- [ ] Rebuild templates, dynamic routes, and listing/pagination
- [ ] Reimplement SEO tags, structured data, and feeds
5. Redirects
- [ ] Write 301s for every changed URL (old → new)
6. QA
- [ ] Verify content parity, media, internal links, and SEO metadata
- [ ] Check Core Web Vitals and build times
- [ ] Cut over DNS; keep the old site reachable until traffic confirms clean When to switch from WordPress
Headless isn't automatically better than WordPress. WordPress is a great blog and a fine small-business site. Consider switching when specific pain shows up, not because "monolithic bad."
The signals to watch:
- Plugin bloat is now a maintenance job. When 25–40 active plugins each need updates, and each update is a small game of "will this break the site," you've turned a website into an operations burden. Every plugin is third-party code with its own release cadence, security surface, and abandonment risk.
- Multiple contributors are stepping on each other. WordPress's editing model strains once several people publish concurrently across many post types, especially with page-builder plugins in the mix.
- You want the same content in more than one place. A marketing site, a mobile app, an in-product help center. WordPress couples content to one PHP-rendered frontend; headless serves content over an API to anything.
- Performance is a plugin arms race. You're paying for a caching plugin to undo the cost of the other plugins, plus a managed host to keep it upright.
- Security patching never ends. The WordPress core plus the plugin surface is the most-attacked stack on the web, and the patch treadmill is yours to run.
If none of that is true, stay. If two or more are, keep reading. (For the broader "is this even the right move" decision, see the content modeling guide. A bad model is the most expensive migration mistake you can make.)
Before you migrate: the audit
Skipping the audit is how a "two-week migration" becomes a two-month one. You can't map what you haven't inventoried.
Content types
List every post type: default posts and pages, plus custom post types from themes and plugins (portfolio items, events, products, team members). For each, note the fields, including Advanced Custom Fields groups and raw post meta. Most WordPress sites have accumulated meta fields nobody uses; the audit is your chance to drop them instead of faithfully porting cruft.
Plugins → capabilities
This is the real work, and it's the answer to "can one CMS replace my plugin stack." Don't migrate plugins; migrate the capabilities they provide. Sort every active plugin into three buckets:
- Built into a headless CMS. SEO metadata fields, image optimization and delivery, localization, revision history, roles/permissions, webhooks. In a capable headless CMS these are platform features, not add-ons you install and patch.
- Moves to the frontend or build layer. Contact forms (a form service or serverless function), caching (static output handles it), sitemaps and RSS (generated at build), redirects (edge/CDN rules).
- Real architectural decisions. WooCommerce, membership/paywall, complex page builders, LMS. These don't map to a checkbox. They become deliberate choices about separate services or headless-commerce backends. Flag them early; they drive the timeline.
Write the mapping down plugin by plugin. The list is your scope.
Media
Count your assets and total size, and note where they're served from: the WordPress uploads directory, or already offloaded to S3/a CDN. Media is usually the largest, slowest part of the import, and body content is full of hard-coded wp-content/uploads/... URLs that will 404 the moment you move. Plan to import media first, capture the new URLs, then rewrite references in post bodies.
Redirects & SEO
Export every URL that's currently indexed: pull the XML sitemap and cross-reference Google Search Console so you catch URLs the sitemap misses. This becomes your redirect map. If your permalink structure changes at all (WordPress /2019/03/slug/ dated permalinks are a common offender), every changed URL needs a 301. Also capture per-page titles, meta descriptions, canonical tags, and any structured data so parity is verifiable after cutover.
i18n
If you run WPML or Polylang, document exactly how translations are stored and linked, and how language URLs are structured. This is the piece most likely to be modeled badly in the new CMS. Model locales as per-locale entries of one content type, not a duplicate content type per language. (More on that pattern in the content modeling guide.)
The migration, step by step
1. Export
Two viable paths out of WordPress: the built-in WXR export (Tools → Export, an XML dump) or the WordPress REST API (/wp-json/wp/v2/...) for structured, paginated JSON. The REST API is usually cleaner for scripting because you get JSON directly and can page through post types and taxonomies programmatically. Normalize whatever you pull into a structured intermediate file (JSON or CSV) that you can regenerate. You will run the export more than once. Convert post HTML to your target body format here, and strip shortcodes and page-builder markup that won't render outside WordPress.
2. Map & model
Take the audit's type list and build the content model in the new CMS: a content type or collection per WordPress post type, fields resolved to keep/merge/drop, and relationships (author, category, related posts) expressed as references rather than duplicated data. Get this right before you import a single row. Remodeling after you've loaded thousands of entries is the expensive path.
3. Import via API/CLI
Don't hand-enter content. Script the import against the CMS's API or command-line tool so it's repeatable and diffable. Order matters: import media first and capture the returned asset URLs, then load entries with body references rewritten to the new URLs. Do a dry run on a subset (a dozen posts across each type), diff the result against the source, fix the mapping, then run the full load. A repeatable import means you can iterate on the model and re-run cleanly instead of manually patching a botched one-shot.
4. Rebuild the frontend
Headless decouples content from presentation, so the frontend is now yours to build in whatever framework you want: Astro, Next.js, SvelteKit, Nuxt. Fetch content over the API (at build time for a static site) and render pages, dynamic routes, listings, and pagination. Reimplement the SEO layer explicitly: title/meta tags, canonical URLs, Open Graph, structured data, sitemap, and RSS. This is also where a lot of the hosting savings come from: static output on a CDN instead of PHP rendering on every request.
5. Redirects
Turn the URL map from the audit into 301 redirects, old → new, for every URL that changed. Handle these at the edge/CDN or in your host's redirect config, not in application code. Redirects are the single most common way a migration tanks organic traffic. A URL that 404s is a ranking you deleted.
6. QA
Before cutover, verify:
- Content parity: spot-check every content type; confirm counts match the source.
- Media: images resolve, at the right sizes, through the new delivery path.
- Internal links and redirects: crawl the new site; test a sample of old URLs and confirm each 301s to the right place.
- SEO: titles, descriptions, canonicals, and structured data carried over.
- Performance: Core Web Vitals and build times are where you expected.
Then cut over DNS, and keep the old WordPress instance reachable (not indexed) until analytics confirm clean traffic on the new stack.
Timeline and cost reality
Expect 4–8 weeks for a typical content site. Roughly a week to audit and model, a week or two to build export/import scripts and rebuild the frontend, and the balance for redirects, QA, and cutover. Industry migration write-ups (2025) quote the same general range for standard content sites. Larger sites with many custom post types and plugin-driven features run longer, and a small blog can be days, not weeks.
On cost, the move usually pays off in three places:
- Hosting. Trading a LAMP stack (PHP + MySQL + a managed WordPress host) for static/Jamstack output on a CDN plus a managed CMS commonly reduces hosting spend, with reported reductions frequently in the 25–40% range, per industry migration write-ups (2025).
- Plugins. Paid plugin subscriptions (SEO, caching, forms, security, backups) collapse into platform features or a couple of build-time tools.
- Maintenance. The update-and-pray patch treadmill (core plus dozens of plugins) largely goes away with a managed CMS and a static frontend that has almost no runtime attack surface.
The counterweight: you're taking on a frontend build and a content model you have to design well. That's real up-front engineering. The trade is worth it when the recurring plugin/maintenance/hosting drag exceeds the one-time build, which is exactly the "when to switch" list above. It's the same trade developers keep making when they leave WordPress: fewer moving parts you don't control, in exchange for owning the frontend and no longer running a permanent patch-and-plugin maintenance job.
Doing it with Adapto
Where a generic guide stops at "import via the API," Adapto CMS is built for exactly the scripted, repeatable import the checklist calls for.
- Import runs through the CLI, not the API. Adapto's public REST API is read-only: it's for fetching content into your frontend, not writing to it. All writes, including a migration import, go through the
adaptoCLI:adapto auth loginto authenticate,adapto files upload ./fileto land media first (capturing the returned URLs for the rewrite step), thenadapto articles create(oradapto pages create/adapto collections items createfor other content types) per entry, with--jsonfor scriptable output and--media-jsonto attach media on create. Translations go throughadapto articles create-translationthe same way, keyed to the source viatranslation_of_id. Wrap those calls in your import script (one call per row,--jsonoutput diffed before the full load), and step 3 becomes a dry-runnable, re-runnable script instead of manual data entry. There's no separate bulk-import command; runadapto llm-infofor the full, current command reference, and see the migrating-content docs for the concrete import path. - The plugin stack collapses into platform features. Image optimization and delivery ride on a bundled media CDN served from
media.adaptocms.com(no separate Cloudinary bill), included on every tier, not gated behind a plan. Localization is field-level and built in: you author a piece and its translations together, all at once, rather than bolting on a translation plugin. Webhooks drive rebuilds on publish. Several of your audit's "built-in" bucket items are already there. - Predictable cost after you land. The whole point of leaving a plugin-and-host cost stack is not to recreate an unpredictable one. Adapto is flat-rate pricing: Free Evaluation at $0, then Hobby $29/mo, Startup $69/mo, Scale $249/mo, Professional $449/mo, with every feature on every tier, unlimited contributors, and no overage fees. No per-seat math, no metered API surprises: the post-migration bill is the one on the page.
- REST reads, no GraphQL to learn. The rebuilt frontend fetches content over a plain REST API, so there's no query-language paradigm layered on top of the migration. Writes (including the import itself) go through the CLI, per the point above.
If you're weighing headless options while you're at it, the same audit-and-map discipline applies whether you land on Adapto, a Contentful alternative, or a Strapi alternative. The checklist above is portable. What differs is how much of your plugin stack the platform absorbs for free, and how boring the import step is.
FAQ
How long does a WordPress to headless migration take?
Most content-site migrations land in a 4–8 week window: about a week to audit and model, a week or two to build export/import scripts and rebuild the frontend, and the rest for redirects, QA, and cutover. Sites with many custom post types and plugin-driven features run longer; a small blog can be done in days. The single biggest timeline risk is the plugin audit: features you didn't realize a plugin provided.
Does migrating off WordPress reduce hosting costs?
Usually, yes. Moving from a LAMP stack (PHP + MySQL + a managed WordPress host) to a static/Jamstack frontend on a CDN plus a managed headless CMS typically cuts hosting bills (reported reductions commonly fall in the 25–40% range) on top of dropping paid plugin subscriptions and shedding a security-patching workload. The offset is the one-time cost of building the new frontend.
Can one CMS replace my WordPress plugin stack?
Mostly. Many plugins map to built-in headless CMS features (SEO fields, image optimization, localization, webhooks, roles) or move to your frontend/build layer (forms, caching, sitemaps, redirects). A handful (advanced e-commerce, membership, complex page builders) become deliberate architectural choices rather than a one-click install. The plugins → capabilities step of the audit is where you decide which bucket each one falls into, and that list becomes your migration scope.