Migrate from WordPress to Drupal: what the move involves
If your WordPress site has outgrown its plugins or needs Drupal's content modeling, plan the move as a content and structure rebuild, not a file copy. WordPress posts, pages, custom post types, taxonomies, comments, and media have to be mapped onto Drupal content types, fields, taxonomy vocabularies, and media entities, and the effort depends on how many custom post types, plugins, media files, and external integrations the current site uses. The Drupal target is a new site built alongside the existing one, not an in-place upgrade, so the WordPress site keeps running until the new one is verified. Ask any partner to inventory those four areas before quoting, because an inventory is what turns an open-ended estimate into a fixed-scope one.
Start the inventory with the WordPress export and the database. A WXR export carries posts, pages, comments, categories, tags, and attachment references, but it does not carry your theme logic, plugin behavior, or shortcodes embedded in post bodies, so each of those needs its own decision: rebuild, replace with a contributed Drupal module, or drop. Confirm which WordPress plugins hold business data, such as forms, memberships, or product records, because those usually need their own mapping rather than a content import. Also confirm the Drupal version and PHP version your hosting will run, since Drupal 11 requires PHP 8.3 or later according to Drupal.org, and the Drupal core release schedule lists Drupal 12 for the week of December 7, 2026.
Treat the WordPress Migrate module as the part of the plan that needs the most scrutiny. Confirm its current release status on Drupal.org before you commit, and if it is still at alpha, plan for code changes, a test harness, and a fallback importer such as a custom migration built on the core Migrate API. Build rollback into the plan from the first test run: each migration should be repeatable, its results should be checkable against the source counts, and a rollback should return the Drupal site to an empty state for that migration. Schedule at least one full dress rehearsal on a copy of production content, and agree with the client who signs off each content type, redirect rule, and media check before cutover.
Which WordPress content maps cleanly to Drupal and what does not
This table compares common WordPress content and site features with their closest Drupal equivalents and marks which ones need manual rebuilding. Read each row as a planning question: if the Drupal side is a clean match, the migration is mostly mapping; if it is a rebuild, budget review and build time for it before the migration starts.
| WordPress item | Drupal equivalent | Migration outlook |
|---|---|---|
| Posts | Content type (for example, Article) with body, summary and author fields | Maps cleanly; confirm field mapping for post formats and custom fields |
| Pages | Content type (for example, Basic page) with menu and alias settings | Maps cleanly; parent-child hierarchy needs an explicit mapping decision |
| Comments | Comment entities attached to content types, with moderation settings | Usually migrates; confirm threading, status and author data in the version in use |
| Media library items | Media entities with image, file and document media types | Partly clean; embedded media in post bodies often needs a second pass |
| Categories and tags | Taxonomy vocabularies with term references on content | Maps cleanly if they are separate vocabularies; hierarchy must be decided up front |
| Users and roles | Drupal users and roles, with password reset on first login | Accounts migrate, but password hashes and role mapping need testing |
| Menus | Menu links and menu blocks built in Drupal | Links usually migrate as static items; dynamic menus are rebuilt by hand |
| Custom post types | Custom content types with fields, built as configuration | Needs a content model decision; the migration source must be mapped per type |
| Custom fields (ACF or similar) | Fields on content types, or Paragraphs for repeating blocks | Simple fields map; nested or conditional fields usually need rebuilding |
| Shortcodes | Text filters, custom render elements or Paragraphs | Does not map automatically; each shortcode must be inventoried and rebuilt |
| Page builder layouts | Paragraphs, Layout Builder or theme components | Does not map automatically; expect manual rebuild of layouts |
| Plugin-generated features (forms, galleries, SEO output) | Contributed Drupal modules or custom code | Rebuilt per feature; confirm equivalents for each plugin in use |
Documented import paths from WordPress into Drupal
Drupal has no single supported WordPress importer that every team can rely on, so the path you choose depends on your export format and on how much you trust each module's release status. The cards below cover the WordPress Migrate module, the core Migrate API, Migrate Plus, and the Drush commands that run, roll back and repeat imports.
WordPress Migrate module with WXR input
The WordPress Migrate module reads a WXR export file produced by WordPress and maps posts, pages, comments, media, tags and categories into Drupal entities. It is the most direct route, but it has only alpha releases, so confirm its current release status on Drupal.org before you commit to it. Ask the team whether the module supports your Drupal version and which WordPress data types it covers, then test a full import on a copy of your site.
Core Migrate API as the foundation
The core Migrate API defines the source, process and destination plugins that every Drupal import uses, including imports built from a WordPress export. When a contributed WordPress module does not cover a data type, such as custom post fields or shortcode-heavy bodies, you write your own migration YAML and plugins on the same API. Plan that custom work as part of the estimate, because it is the part most likely to grow.
Migrate Plus for other exports
Migrate Plus adds source plugins for CSV, JSON, XML and other feeds, which helps when WordPress content has been exported through a database dump, a REST response or a spreadsheet instead of WXR. It is also useful for supplementary data such as author profiles or redirect lists that WXR does not carry. Confirm each source format with a sample file before deciding which plugin reads it.
Migrate Tools for Drush runs
Migrate Tools provides Drush commands to list, import, roll back and reset migrations. Rollback matters most for WordPress projects, because a mapping error discovered after launch can then be reversed without rebuilding the site. Test the full cycle of import, rollback and re-import on a staging copy, and record the commands and their order in the runbook.
Alpha status as a delivery risk
An alpha release signals that the API, field handling and test coverage may still change. Before you rely on any alpha module, check its issue queue for open data loss reports, confirm whether it is maintained, and budget for a fallback path built on the core Migrate API. Agree in writing which party owns fixes if the module changes during your project.
How the WXR export and Migrate pipeline moves content
The pipeline starts with a WXR export taken from the WordPress admin, which writes posts, pages, comments, attachments, categories and tags into one XML file. Each WordPress post type becomes a candidate Drupal content type, and each taxonomy (categories and tags) becomes a candidate vocabulary. Decide these mappings before any migration runs: a custom post type with its own fields usually needs its own content type, while plain posts and pages often map to a single article-style type with a flag for pages. Attachments in the export carry file references but not the binary files, so media needs a separate copy step into Drupal's file system and a Media entity for each item. Confirm that the export contains everything you need, including comment threads and author records, by opening the XML and checking a sample post against the live site.
Internal links and shortcodes are where most content is lost in transit. WordPress links often point at absolute URLs on the old domain, and body text may contain shortcodes or block markup that Drupal does not render. Plan a rewrite pass that converts known internal URLs to Drupal node references or path aliases, and a decision for each shortcode: map it to a Drupal filter or paragraph type, or convert it to plain markup during migration. Your source baseline also matters. WordPress.org recommends PHP 8.3 or greater and MariaDB 10.11 or greater or MySQL 8.0 or greater, and the current release is WordPress 7.1, so confirm the versions on the existing host before you plan the export. Drupal 11 requires PHP 8.3 or later, so the target and source can share a PHP baseline, but the two stacks still need separate hosts or containers during the migration window.
Treat the WordPress Migrate module as a dependency with its own risk. Check its release status on Drupal.org before you commit to a build, because a module that has only alpha releases may change its mappings or source plugins between versions. Keep the migration repeatable: run each migration into a staging copy, compare record counts and sample pages, and test rollback with the Migrate Tools commands before the production cutover. Ask any partner to state which module version is pinned, how its gaps will be handled in writing, and what happens to comments and media that fail to import.
How the migration runs from inventory to decommission
The sequence moves a WordPress site into Drupal in controlled stages, so each content type, plugin replacement and redirect is proven on a sample before the live site changes. Each phase closes with a written output that the next phase depends on.
Inventory content types, plugins and integrations
Map every WordPress post type, custom taxonomy, custom field, shortcode, plugin and external integration, such as forms, payments, search or newsletter tools. DeployOpen's team works with your editors and site owners to record which features are content, which are behavior and which can be retired. The step is done when each item has a named Drupal target, such as a content type, a contributed module or a custom build, and an owner who has signed off on it.
Confirm the migration module and its release status
Before anything is built, check the WordPress Migrate module's current release state, its Drupal core compatibility and its open issues on Drupal.org. Confirm the WXR export options your WordPress version produces, including media and attachment handling. Record any module that is still alpha as a named risk with a fallback, such as a scripted import with the core Migrate API. The step is done when the module choice, its version and the fallback are written into the project plan.
Run a pilot migration on a representative sample
Select a sample that covers the hard cases: long posts with embedded media, posts with custom fields, categories and tags with the same names, comments, and pages with custom templates. Run the migration into a non-production Drupal instance and compare results field by field with the source. The step is done when the sample passes a checklist the content owners agreed on, and every gap has a recorded fix or an accepted exception.
Test rollback and repeated runs
Run the full migration, roll it back with the migration tools, and run it again to confirm that rollback leaves no orphaned entities, files or aliases. Test an incremental run that picks up posts edited after the first pass. Check that media files and URL aliases behave the same on each run. The step is done when a clean rollback and a clean re-run are both documented with the results.
Build redirect mapping and verify it
Create a table that maps every old WordPress permalink, including category, tag, date and pagination URLs, to its new Drupal path. Load the mapping into the redirect layer and test a sample of old URLs against the staging site. Check that search engine metadata and sitemaps are carried across. The step is done when every mapped URL returns the intended destination and the list of unmapped URLs is reviewed and accepted.
Operate both sites in parallel
Keep WordPress live while Drupal runs on a staging or pre-production address that is refreshed from the source. Editors check content on both sides, and any differences in comments, media or forms are logged and resolved. Agree in advance how long the parallel run lasts and who decides when it ends. The step is done when the content owners confirm the Drupal output matches the agreed checklist across repeated refreshes.
Cut over with redirects and DNS
On the agreed change window, run the final migration, freeze WordPress editing, point DNS to the Drupal hosts and activate the redirect map. Monitor error logs, redirect hits and 404 responses, and keep the rollback path documented until the team accepts the new site. The step is done when the live address serves Drupal, the redirect map is confirmed in production and the cutover record is signed off.
Decommission WordPress after a stable period
Keep the WordPress instance in read-only mode for a period the owners agree on, then archive its database, uploads and plugin configuration to retained storage. Remove its public access, revoke its credentials and update the inventory and backup records. The step is done when the archive is verified, access is removed and the decommission record lists where the retained copies are held.
What drives the cost and duration of a WordPress to Drupal move
This table lists the factors that change the effort of a WordPress to Drupal move, how each one pushes cost or duration, and what to confirm before asking for a quote. Read it as a checklist for your own inventory: the more of these factors your site has, the more discovery and mapping work a written scope needs.
| Driver | Why it changes effort | How to keep it down |
|---|---|---|
| Custom post types and custom fields | Each custom post type needs a Drupal content type, and each custom field needs a mapped field, often with its own transform logic. | Inventory post types and fields early, and retire unused ones before mapping starts. |
| Plugin dependence | Page builders, forms, SEO and e-commerce plugins store content in shortcodes or proprietary tables that have no direct Drupal equivalent. | List active plugins, keep only those whose data must move, and decide which features are rebuilt in Drupal. |
| Media volume and file storage paths | Attachments, image sizes and paths embedded in post bodies must be copied, deduplicated and rewritten to Drupal media entities. | Audit the uploads folder, remove orphaned files, and agree on a storage location and naming scheme before the first test run. |
| Comment volume and moderation | Large comment threads need mapping to Drupal comment entities, and spam or pending states must be carried over correctly. | Decide which comments are historical, archive the rest, and confirm how many approved comments must appear on the new site. |
| Multilingual needs | Translated posts, language plugins and per-language URLs each add mapping, configuration and testing work. | Confirm the languages in scope and whether translations migrate now or later. |
| URL and SEO redirect requirements | Every indexed URL that changes needs a redirect, and permalink structures, taxonomy archives and feeds must be mapped. | Export the current URL list from your analytics or crawl data, and agree which URLs must keep their paths. |
| Integrations with CRM or identity systems | Forms, single sign-on and CRM hand-offs must be rebuilt and tested against the new site, not copied. | Name each integration in the written scope so it is priced and tested as its own piece of work. |
| Editorial team readiness | Editors who must learn new content types, the media library and workflows add review cycles and training time before cutover. | Schedule content owner reviews during discovery and plan a trial editing period on the staging site. |
| Cost components | Discovery and mapping, the build of content types and Migrate mappings, and testing and cutover each carry separate effort. | Ask for a quote that lists these three components with the drivers above, since quotes follow from written scope. |
What usually goes wrong in WordPress to Drupal migrations
Most WordPress to Drupal problems are not exotic. They come from a migration module still in alpha, content that refers to other content by path or shortcode, and a live site that keeps changing while the new one is being built. Each card below names one of these failure points and the check that catches it before cutover.
Alpha-stage migration module risk
The WordPress Migrate module is the component that moves content, and it should be treated as a dependency with its own release risk rather than a finished tool. Confirm its current release status on Drupal.org before the project is scoped, and record which WordPress versions and plugins it was tested against. Plan for code review of the mapping, pinned versions in Composer, and enough time to patch or replace parts of the migration if the module changes or stops receiving fixes.
Broken internal links and shortcodes
WordPress content often embeds shortcodes from plugins, and internal links point to absolute WordPress URLs. Neither survives a move unchanged, so the body text can render raw bracketed tags or dead links after import. Inventory the shortcodes in use, decide whether each becomes a Drupal filter, a paragraph or a rebuilt element, and run a link crawl on the migrated site to find references that still point at the old domain.
Lost URL structure and SEO equity
Permalink structures such as dated paths or category prefixes determine which pages search engines already index. If the Drupal URL aliases differ and no redirects are written, rankings and inbound links are lost at cutover. Export the full list of live URLs from the WordPress site, map each to its new path, and test the redirect table against that list before DNS changes. Confirm the redirect rules with the team that owns search performance.
Comment and user identity gaps
WordPress comments and authors are linked to user accounts that may be missing, duplicated or stored with different email addresses. Drupal requires each content author and comment owner to resolve to a valid account, so orphaned records can fail or be silently reassigned. Decide early whether comments migrate at all, how anonymous comments are stored, and which authors receive accounts. Check that passwords are not carried across insecurely and that imported accounts have the roles they need.
Media path breakage
Images and files in WordPress live under the uploads directory, often with resized variants generated for each size. Migrated body text may still reference the original paths, and the Drupal Media entities may not match the variants the old theme expected. Copy the uploads directory with its folder structure, confirm that every referenced file exists in the new file system, and check image rendering on representative pages rather than trusting the migration summary.
Drift between live site and parallel run
A parallel run keeps the Drupal build fed with content while WordPress stays in production. Editors continue to publish, plugins update, and new comments arrive, so each test pass sees a different dataset. Freeze the mapping before each rehearsal, record the source timestamp for every run, and plan a final delta import with a named cutover window. Ask the vendor how rollback works if the delta import fails halfway.
Questions teams ask before moving from WordPress to Drupal
How much does a WordPress to Drupal migration cost?
Cost depends on the scope you define, not on a fixed rate. The main cost components are discovery and content modeling, the migration build and mapping work, the rebuild of your theme and any plugin functionality, testing, and cutover. Most of this is one-time work. Recurring costs come after launch, in hosting, updates and support, which you will carry whether or not a partner is involved. DeployOpen does not publish a price list, so ask for a quote built from a written scope that lists your content types, volume of media, plugins in use, integrations and languages. Ask the quote to separate build, testing and post-launch support so you can compare options fairly.
How long does a WordPress to Drupal migration take?
Duration is driven by how much of the site is content and how much is custom behavior. A site with standard posts, pages, tags, categories and a modest media library is simpler than one with custom post types, membership rules, forms, search and many integrations. Other drivers include the number of content owners who must review samples, the number of rounds of sign-off, and how many rollback and dry-run cycles you want before cutover. No duration figure is given here because none has been researched for this topic. Ask for a timeline in the written scope, with milestones for mapping, a trial import, review and cutover.
What does our team need to provide during the migration?
Most delays come from missing decisions rather than missing code. Expect to provide named content owners who can approve how each content type maps, a sign-off authority for the staging site and for cutover, read access to the WordPress database or WXR exports, and administrative access to a staging Drupal environment and the infrastructure it runs on. You will also need an inventory of plugins, shortcodes, custom code and redirects that search engines or users depend on. Agree in writing who approves the trial import, who tests the rollback, and who owns the DNS and redirect changes at cutover.
Can our in-house team migrate WordPress to Drupal?
An in-house team can do it if it has Drupal experience, especially with the Migrate API, custom modules and theme building, and if it can keep a staging environment running through testing. The harder part is the decision work: content modeling, deciding which WordPress features to rebuild and which to drop, and proving that rollback works before cutover. Ask yourself whether your team has built a Drupal site from content types to a migration, and whether it can take on the ongoing updates afterward. Where those skills are missing, a fixed-scope partner engagement can cover the build while your staff learn the platform.
Will our WordPress plugins work on Drupal?
Usually not directly. WordPress plugins are written for WordPress's own code, so they do not run inside Drupal. The question to ask for each plugin is what it does for your site: whether it stores content you need to keep, provides a feature you need to rebuild, or only adds a convenience. Content stored by a plugin may need its own mapping. Features are typically rebuilt with Drupal contributed modules or custom code. Confirm with the maintainers of each Drupal module you plan to use which capabilities it supports and which versions of Drupal it is compatible with before you commit to it.
Is the WordPress Migrate module ready for production?
Treat it as a risk to manage, not as a settled dependency. The WordPress Migrate module has only alpha releases, which means its API and behavior may change and it may not cover every WordPress data shape you have. Before relying on it, read its project page on Drupal.org, check its open issues against your content, and test it on a copy of your data. Where it falls short, plan for custom migration source code or a WXR-based import. Ask the module maintainers which releases they recommend for your Drupal version and whether they accept the gaps you find.
How do we test rollback before the live cutover?
Test rollback on a full staging run, not on a sample. Run the migration, record the imported entity IDs, then use the rollback command of the migration tooling to remove them and confirm the site returns to its pre-import state. Repeat the cycle until the import and rollback both complete cleanly on a fresh copy of the WordPress data. Also check redirects, media paths, comment threads and taxonomy terms after each run. The rollback test should be signed off by the same person who approves cutover, and it should be repeated after any change to the source data. Confirm the exact commands and their behavior with the migration module's documentation.
Should we keep WordPress running while we build Drupal?
Yes, in most cases. Keeping WordPress live until cutover lets you keep publishing while the build proceeds, and it gives you a working fallback. The trade-off is that content entered during the build must be migrated again, so plan a final incremental run and a freeze window before cutover. Also keep WordPress patched during this period. WordPress.org states that only the latest version is officially supported, although its Security Team backports critical fixes to older versions, so keep the site on the current release line throughout the project.
Confirming the Drupal and WordPress versions before scoping
Start by confirming both ends of the move, because the versions decide how much work the migration becomes. On the WordPress side, WordPress 7.1.3 is the latest release in the 7.1 series, and the WordPress.org releases archive says only the most recent release in that series is actively maintained. Record the exact core version, the PHP version and the database engine of the source site, then check them against the WordPress.org requirements page, which recommends PHP 8.3 or greater and MariaDB 10.11 or greater or MySQL 8.0 or greater. A site that is several minor releases behind or runs an older PHP build will need upgrading before any export is trustworthy.
On the Drupal side, Drupal 11.4 was released the week of June 29, 2026, and Drupal 12.0.0 is scheduled for the week of December 7, 2026, according to the Drupal core release schedule. Choose the target version early, because it sets the minimum PHP version, the hosting image and which contributed modules you can install. Drupal 11 requires PHP 8.3 or later and Drupal 12 requires PHP 8.5 or later, so a target on Drupal 12 changes the server build as well as the migration plan. Confirm with your team and the migration module maintainers which Drupal version the WordPress Migrate module supports before you commit to a target, since a module that lags a core release can force a choice between waiting and running an unsupported combination.
Put the chosen versions in the scope document as explicit assumptions, with the date each was checked. That record lets the migration team re-test the mapping if the target moves, and it lets the procurement and security reviewers see which PHP, database and core releases the estimate depends on.
How DeployOpen scopes, delivers and supports a WordPress to Drupal migration
DeployOpen plans and builds self-hosted Drupal inside your own infrastructure, so a WordPress to Drupal migration is scoped in writing before any content moves. The work runs in stages that you can review, test and roll back, and it ends with documentation your team can operate.
How we scope
- Engagements are fixed-scope, with the WordPress sites, content types, plugins and integrations in writing before work starts.
- The written scope lists which posts, pages, comments, media, tags and categories move, and which are excluded.
- We record the WordPress version, hosting and plugin inventory so the migration plan matches your real source site.
How we build
- We map WordPress fields and taxonomies to Drupal content types and vocabularies in a reviewed mapping document.
- Migrations run from a WXR export or the WordPress Migrate module in a staging environment, with each run repeatable.
- Rollback is tested on the staging site, and media paths, redirects and comment handling are verified before cutover.
How we hand over
- You receive the migration code, mapping documentation and run instructions in a repository your team controls.
- Handover includes a checklist of content counts, URL redirects and rebuilt templates for your editors to sign off.
- Known gaps, such as plugin functionality that must be rebuilt by hand, are recorded with owners and next steps.
How we support
- Post-launch support is available as a retainer covering Drupal updates, backups and monitoring of the new site.
- A retainer can also cover planned checks of the WordPress Migrate module as it moves toward a stable release.
- Ask for the support scope, response arrangements and upgrade path to be written into the same agreement as the build.

