Ghost CMS

Migrate WordPress to Ghost, step by step

Ghost has a built-in WordPress migrator, and on a simple blog it does most of the work. The planning is for everything it leaves out: custom post types, unusual shortcodes, subscribers and old URLs.

By itmarkerz Technologies. Updated 30 October 2026.

What the migrator does and doesn’t carry over

What Ghost's WordPress migrator imports
Comes acrossDoesn’t come across
Posts and pagesCustom post types
Some shortcodes, such as [caption], [audio] and [code]Most uncommon shortcodes
Most [vc_] and [et_] page-builder shortcodesPlugins that change access to content
Categories, which become tags. A post’s first category becomes its primary tagSubscribers and members, which are a separate step

From Ghost’s WordPress migration guide, checked on 30 October 2026. The guide doesn’t say how images are handled, so check them in your trial import.

Step 1: Decide if Ghost still fits

If custom post types carry real weight on your site, such as case studies or events with their own fields, Ghost has no direct equivalent, and you would be flattening them into posts and tags. Read Ghost vs WordPress before going further. Also decide where it will run: Ghost(Pro) or self-hosted. A self-hosted install must have Mailgun for bulk newsletters.

Step 2: Audit WordPress

Write down what you have, so nothing important disappears by accident.

wp post-type list --public=true
wp post list --post_type=post --format=count
wp post list --post_type=page --format=count
wp plugin list --status=active
wp option get permalink_structure

Check the post count against the 2,500 limit and the export size against 100 MB. For each active plugin, note what it does and what replaces it on Ghost. Contact forms, in particular, need a replacement, because Ghost’s built-in forms are for sign-ups. Export your indexed URLs from your sitemap and Search Console, because you’ll compare against that list at the end.

Step 3: Run a trial import

  1. Set up a staging Ghost site, separate from the one you will launch.
  2. Log in to WordPress, then in Ghost Admin go to Settings, Advanced, Import/Export.
  3. Enter your WordPress site’s public URL and continue.
  4. Use the link to open WordPress’s export settings, select all content, and download the XML file.
  5. Upload the file to the migrator and review the post and page counts it reports.
  6. Import, then read a sample of your oldest, longest and most media-heavy posts.

If the file is over the limit or the structure is unusual, use TryGhost/migrate instead. Check for leftover shortcodes, missing images and broken embeds, then fix what you can in WordPress or in the import process, since repeat imports are the cheap way to get this right.

Step 4: Build or choose the theme

Ghost themes use Handlebars. Starter plans on Ghost(Pro) can’t use custom or Marketplace themes, so a custom design means Publisher or above. Build against the imported posts instead of placeholder text, because real headlines and old images show the problems. Validate the theme with GScan, Ghost’s own validator.

Step 5: Move members

Export subscribers from your WordPress plugin or email platform, clean the list, and format it as a CSV for Ghost’s member import.

email,name,note,subscribed_to_emails,stripe_customer_id,complimentary_plan,labels,created_at
ana@example.com,Ana Example,,true,,false,"from-wordpress, customer",2024-05-01T09:00:00.000Z
  • Only email is required.
  • Keep each person’s real opt-in state in subscribed_to_emails. Don’t turn everyone on.
  • For paid subscribers, connect Stripe first, then use a customer ID or auto in stripe_customer_id.
  • Label the batch, so you can find these members later.

Ghost also has guides for moving from Mailchimp, Substack, Kit, Beehiiv and others, if your list lives there. Importing a list has deliverability consequences as well, covered in Ghost newsletter setup for B2B.

Step 6: Write the redirects

Ghost’s redirects tutorial gives common WordPress rules. A redirects.yaml file holds them, and you upload it in Ghost Admin. Use the rules that match your permalink setting:

301:
  ^\/category\/(.*): /tag/$1
  ^\/[0-9]{4}\/[0-9]{2}\/[0-9]{2}\/(.*): /$1
  ^\/[0-9]{4}\/[0-9]{2}\/(.*): /$1

Then test the list you exported in Step 2. Every old URL should land on a live page with one redirect. Pages that have no new home need a decision, such as a redirect to the nearest page, instead of a pile of 404s. Don’t use this file for www, HTTPS or trailing-slash rules, since Ghost’s tutorial sends those elsewhere.

Step 7: Go live

  1. Freeze publishing on WordPress and run the final import.
  2. Import the final member list, and check the member count.
  3. Connect Stripe and test a real paid sign-up, if you sell subscriptions.
  4. Send a test newsletter to your own addresses, and read it in several mail clients.
  5. Point DNS at Ghost, and confirm SSL.
  6. Run the URL list again on the live domain, and resubmit your sitemap in Search Console.
  7. Keep the WordPress site and a backup available until you’re sure nothing is missing.

When to get help

A blog with standard posts and a clean permalink setup is a reasonable project to do yourself. Get help when you have custom post types, a large back catalogue, page-builder content or paying members. Our Ghost development service covers the theme, the move and the redirects, and we quote at a fixed price once we have seen your content. Tell us about your site. We have no published Ghost case study. Most of our work is delivered under NDA, so many projects cannot be named.

Questions

How big a WordPress site can Ghost's migrator handle?

Ghost's guide gives limits of 100 MB for the XML file and 2,500 posts. Larger or more complicated sites can use the open-source tools in the TryGhost/migrate repository, and Ghost(Pro) customers can contact Ghost's migrations team.

Do our newsletter subscribers come across with the posts?

No. The in-app migrator covers posts and pages. Subscribers go in separately, as a CSV in Ghost's member import, or through Ghost's concierge on Ghost(Pro).

Can paying subscribers keep their subscriptions?

If they are already in Stripe, the member import can link them: its stripe_customer_id field takes an ID, or the value auto, which matches by email in your connected Stripe account. If your WordPress plugin bills through something else, plan that move before anything else.

Will URLs change?

They might. Date-based permalinks and category archives usually change, which is why Ghost publishes redirect rules for them. If your WordPress URLs are already /post-name/, posts can usually keep the same address.

More on Ghost

Want a hand with the move?

Tell us your post count, subscriber count and plugins. We will say what can be imported and what needs custom work.

We reply within one business day (IST).