I have moved several sites from WordPress to Craft over the years. The work is rarely about the import script. It is about deciding what to keep, what to redesign and what to retire, then sequencing the build so the live site stays up while the new one comes together. This is a planning-level walkthrough, not a click-by-click tutorial. The names of WordPress and Craft concepts have been stable for long enough that you can use this as a map regardless of what the control panel looks like the day you start.
If you are still weighing the decision rather than executing it, the more general piece on why a migration is usually safer than staying on the wrong platform is a better starting point. This post assumes you have already decided Craft is where you are going.
Why teams move from WordPress to Craft
The reasons cluster into a small set. Founder-led products outgrow WordPress when the content model gets specific enough that ACF starts looking like a workaround rather than a feature. Content teams hit friction when Gutenberg blocks turn into a sprawl of half-similar variants and nobody can remember which one to use for the homepage hero. Plugin sprawl crosses a threshold where every minor update becomes a risk and every security advisory turns into a half-day of work. Performance ceilings get hit where the underlying architecture, not the host, is the bottleneck. Agencies and in-house teams want a cleaner content model with fewer guardrails to fight.
None of these are exclusive to WordPress. Plenty of WordPress sites work well. I have written about WordPress, Craft and Statamic side by side for founders trying to make the choice in the first place. Where Craft tends to win is for teams who care about content modelling and editorial clarity and have a developer available who can take advantage of it.
Audit the WordPress site before you touch Craft
Most of the work in a migration happens before you install Craft. The audit is the part that gets rushed and the part that pays back the most.
Walk through these in order:
Post types. Default posts and pages, plus every custom post type. Each one becomes a candidate for a Craft section.
Custom fields. Almost always ACF in 2026. Map every field group, including conditional logic and repeaters. The export format has been stable for years, which makes this easier than it used to be.
Taxonomies. Categories, tags and any custom taxonomies. Some will map cleanly to Craft categories, others fit better as tags or entry references.
Plugins. Split them into two lists. Plugins that carry business logic such as forms, memberships, e-commerce, search or anything that owns its own database tables. Plugins that only affect display or developer convenience. The first list needs a replacement plan. The second list mostly disappears.
Users and roles. Who logs in, what they need to do, and which permissions matter. Craft has its own user group system that often ends up simpler.
Media library. Total file count, total storage size, the rough mix of formats. Look at how WordPress is generating image sizes. You will rebuild that in Craft.
Multisite. If the source is a WordPress multisite, list every subsite. Each one is a separate migration decision. Some become Craft sites within a single install, some become entirely separate Craft installs.
Comments, search, redirects. Each is a separate decision that comes later. Just note the volumes for now.
The thing that catches every team is plugins that quietly own business logic the team has forgotten about. A loyalty integration written four years ago, a popup builder used on one campaign that still fires, a custom WP-CLI command running in cron. Find these before you scope the build.
Translating the content model
This is where the project either gets easier or harder. A clean content model in Craft makes everything downstream simpler. A muddled one means editors will be confused for the life of the site.
The rough mapping is:
WordPress post types become Craft sections, with one or more entry types each. A blog section with a single entry type, a case study section with two entry types if the layouts differ enough.
ACF field groups become Craft field layouts on those entry types. ACF repeaters become Matrix fields, which is the Craft equivalent and a better fit than a repeater because each Matrix block has its own field layout.
Gutenberg blocks become Matrix block types. This is where the translation gets messy. The Gutenberg block library on a mature WordPress site is often a mix of core blocks, theme blocks, ACF blocks and third-party plugin blocks. Each one needs a decision: keep, redesign or drop.
WordPress taxonomies become Craft categories or tags. Categories when the taxonomy has structure or hierarchy, tags when it is a flat freeform list.
WordPress users become Craft users, grouped into user groups that reflect what they actually do.
The Gutenberg block step is where I see the most teams underestimate the work. A site with 40 different block variants in WordPress will not, and should not, have 40 Matrix blocks in Craft. The migration is the right moment to consolidate down to the 10 or 12 you actually need.
For multilingual sites running Polylang or WPML, the mapping is more involved. Both store translations in WordPress in their own way. Craft has multi-site as a first-class concept, with each language as a separate site that shares a content schema. Plan that mapping carefully. The export side is the hard part. Several community-built scripts exist for both Polylang and WPML, and the WP REST API exposes most of what you need with the right plugins enabled, but expect to write or adapt some glue code.
URL strategy and the redirect map
Preserve every URL you can. SEO is largely a function of which URLs Google has indexed and trusts, and breaking them is the single biggest avoidable mistake in a migration.
Start by exporting a list of every live URL from the WordPress site. Your sitemap is the obvious source, but it will not cover everything, so cross-check against Search Console, Analytics top pages and an actual crawl of the site. You want a single spreadsheet with every URL on one side and its destination URL on the other.
Map the permalink structure to Craft URI patterns. WordPress permalinks like /category/slug or /year/month/slug map to Craft section URI settings. Where you can keep the existing structure, do. Where Craft suggests something cleaner, weigh whether the SEO loss is worth the gain in editorial clarity. Usually it is not for the existing content, but the new content can use the cleaner pattern.
Document every URL that has to change. These need 301 redirects from the old URL to the new one. Build that redirect map before launch, not after. Redirect at the web server level using Nginx or Apache rules where possible, rather than inside the application. Server-level redirects are faster and survive cache clears.
Craft has a redirects plugin in the ecosystem if you prefer that route, but I default to server-level for the bulk redirect map and reserve the plugin for ad hoc redirects editors add later.
Assets and the media library
WordPress generates a fixed set of image sizes and stores them next to the original. Craft handles this differently. You upload the original, and image transforms generate sized versions on demand or at save time, based on transform definitions in the control panel or in code.
Three rules for the asset migration:
Bring across the original-quality file, not the WordPress thumbnails. The thumbnails are throwaway. The original is the source of truth.
Define the image transforms you actually need before the import runs. Hero images, card thumbnails, blog list, OpenGraph. Each transform becomes a named transform in Craft.
Decide where assets live. A local volume on the server, or an S3-compatible volume on object storage, or one of the supported CDN-backed volumes. Pick this before you start importing because moving thousands of assets between volumes after the fact is painful.
Focal points are worth using. Craft asks the editor to mark the focal point of an image once, then every crop respects it. WordPress does not have a clean equivalent, so this is one of the editor-facing wins to highlight in training.
Broken image links are common after a media library import. Crawl staging once content is in place and check every 404 against the originals.
Forms, search, comments
These three are separate decisions, and each one tends to be made too late.
For forms, the established option in the Craft ecosystem covers everything from a contact form to multi-step workflows with conditional logic and integrations. If you are coming from Gravity Forms or Contact Form 7 with submission history you care about, plan how that history moves. Often the answer is to export submissions to CSV from WordPress and leave them outside the CMS rather than try to import them.
For search, Craft has solid native search on the entry index. It is fine for most marketing sites. For larger content libraries or for searches that need to span multiple sections with relevance tuning, an external service like Algolia or Elasticsearch with a Craft plugin in front is the better option. Decide which side of that line you are on before launch.
For comments, the honest answer is that most WordPress sites moving to Craft drop native comments and either use a third-party service like Disqus or remove comments entirely. Importing comments into Craft is technically possible but the editorial weight rarely justifies the work.
SEO carry-over
Yoast or Rank Math has been writing the meta titles and descriptions on the WordPress site, plus OpenGraph tags, schema markup and the sitemap. All of that needs to survive the move.
In Craft, an SEO plugin from the ecosystem handles the equivalent. Pick one and stay consistent. Map the Yoast or Rank Math fields across to its equivalent fields during the import so every entry has its meta title, meta description and OpenGraph data populated on day one.
Other things to carry across explicitly:
Sitemap.xml at the same URL
Robots.txt with the same rules where they still apply
Canonical URL handling for any pages that had explicit canonicals
Schema markup, particularly Article, BreadcrumbList, Organization and FAQPage if you use them
Search Console verification for the new platform, ideally before launch so the property is ready
Custom functionality and the shift from hooks to events
WordPress custom code is almost always built on hooks and filters in functions.php or a custom plugin. Some of it is genuinely custom, some is glue between plugins that may no longer exist on the new platform.
Craft handles the same problems with modules and plugins. Modules are bits of PHP code that live in the site repo and hook into events on Craft elements and services. Plugins are the same idea packaged up. The architectural shift is from imperative hooks scattered through the codebase to event listeners registered in a known place, which is easier to reason about over time.
Categorise the custom code before rewriting:
Display logic that only modified output. Most of this dies, replaced by Twig templates in Craft.
Workflow logic that runs on save or publish. This becomes a Craft module listening to element save events.
Integration logic that talks to third-party APIs. Usually a Craft module with a service class, often a small one.
Anything that owns its own data. Plan that data model in Craft properly rather than porting the WordPress tables verbatim.
Importing the content
For the actual content move, the route I default to is the official import plugin maintained by the Craft team. It reads XML, RSS, ATOM, CSV or JSON feeds and maps them onto entries, categories, users and assets. It handles duplication detection, runs in the background via Craft queues and logs everything.
The pattern is to export WordPress data through the WP REST API or a WordPress export plugin, point the importer at it and tune the field mapping until a small batch lands correctly. Then run it across the full content set. For sites with bespoke field mappings or content that needs transformation in flight, a custom Craft console command using the same source data is often simpler than fighting an off-the-shelf importer into doing something exotic.
The thing that catches every team here is the body content. WordPress stores post bodies as HTML with Gutenberg block markers, or with shortcodes, or with raw HTML. Craft expects either a rich text field or a Matrix structure. Translating one to the other almost always involves manual cleanup on at least the hero pages. Budget time for it. The other approach, where the body stays as a single rich text field, works fine and is faster, but it leaves you with the same editorial limitations you were trying to escape.
Demo the new control panel early
The new editor experience is a feature, not a side effect. Demo it to the content team while the build is still flexible, not when launch is two weeks away. The earlier they see it, the more useful their feedback.
The common editor confusion when moving from WordPress to Craft is the difference between sections, entry types, categories and Matrix blocks. WordPress collapses several of these concepts into a single editor screen. Craft separates them, which gives you more control and a bit more to learn. Walk through the distinction once, hands on, and most editors get it.
A short training session and a one-page reference for the three or four things editors do most often is usually enough. Plan that in rather than treating it as a launch-day surprise.
Cutover and rollback
The cutover plan should be written down before you go anywhere near it.
The shape I use:
Build Craft on staging in parallel with the live WordPress site. The two never share a database. Staging gets full content and a real DNS-less domain.
Run a content freeze on the WordPress site once staging is signed off. New posts wait. This window is usually 24 to 48 hours.
Run a final delta migration covering anything that changed since the previous run. This is where a feed-based importer earns its keep because you can re-run it idempotently.
Switch DNS to the new Craft host. Lower TTLs a day in advance so propagation is fast. A Craft-specific managed platform, a mainstream PHP managed host or a managed VPS, the choice depends on the team rather than the migration.
Verify the redirect map by spot-checking the top 50 URLs and a random sample beyond that.
Monitor for the first week. Search Console for crawl errors, server logs for unexpected 404s, analytics for traffic dips.
Rollback is the part most teams skip writing down. Keep the WordPress site running on its existing host, but not on the public DNS, for at least two weeks after launch. If something catastrophic surfaces, you can flip DNS back and triage without pressure. After two weeks of clean monitoring, archive the WordPress site as a database dump and an asset tarball and decommission the hosting.
What to do next
If you are at the planning stage, the practical move is to do the audit yourself or with whoever is going to deliver the build. Until the post types, fields, plugins and URLs are written down, scoping is a guess.
If you want a second pair of eyes on the plan, or want someone to deliver the migration end to end, get in touch and tell me what the WordPress site looks like. You can also see what Craft CMS development and WordPress development look like as freelance engagements.
Frequently asked questions
How long does a WordPress to Craft CMS migration take?
A small marketing site with a clean content model usually takes 4 to 8 weeks end to end. A larger site with a complex Gutenberg or ACF setup, multilingual content and custom WordPress functionality is more often 3 to 6 months. The audit and content model design takes a third of the total time. The build takes another third. The import, redirects and cutover take the last third.
Will my SEO rankings survive moving from WordPress to Craft?
Yes, if the URL strategy is handled properly. Map every WordPress URL to a Craft URL, preserve the existing structure where you can, and apply 301 redirects at the web server level for anything that changes. Carry meta titles, meta descriptions and OpenGraph data across in the import. Some short-term fluctuation in rankings is normal. Lasting damage almost always traces back to a broken redirect map or missed URLs.
Can I move ACF fields directly into Craft?
There is no one-click import for ACF, but the mapping is straightforward. ACF field groups become Craft field layouts on entry types, ACF repeaters become Matrix fields and ACF flexible content becomes Matrix with multiple block types. The migration is the right moment to consolidate the ACF setup rather than reproduce it verbatim. Sites often discover they have 30 ACF fields they no longer use.
What happens to my Gutenberg blocks in Craft?
Gutenberg blocks become Matrix block types in Craft. The translation is rarely one to one because most WordPress sites accumulate more block variants than they need. The migration is a good moment to consolidate down to the 10 or 12 blocks that matter and either redesign or drop the rest. Body content from WordPress posts almost always needs manual cleanup on the hero pages to fit the new structure.
Planning a WordPress to Craft move?
If you want a second pair of eyes on the migration plan, or someone to deliver it end to end, get in touch and tell me what the WordPress site looks like.
Get in touch