Substack → WordPress
Move Substack posts, images, podcasts, comments, and free or paid subscribers into WordPress.com with the official Substack importer. Keep Substack online until missing images are re-uploaded. Paid readers need the same Stripe account and a mapped newsletter tier.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Substack
- Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box
- Audience, campaigns, automations, and reporting live in one publishing system
- Brand control, automation, data depth, and platform independence are limited
- Automation logic, analytics history, and deliverability settings are not very portable
WordPress
- Unmatched ecosystem breadth and content ownership support almost any publishing model
- Editors get a purpose-built publishing workflow instead of raw files
- Plugin, hosting, security, and performance maintenance accumulate over time
- Themes, extensions, and content models add maintenance and portability constraints
WordPress: Unmatched ecosystem breadth and content ownership support almost any publishing model. This removes a major source-side concern: Brand control, automation, data depth, and platform independence are limited.
What you lose: Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box. What you inherit: Plugin, hosting, security, and performance maintenance accumulate over time.
Jump to a section
Know the shape of the move.
This timeline assumes
- One Substack publication with up to 2,000 posts, 50,000 subscribers, and optional paid tiers on Stripe
- You use WordPress.com's Substack importer, or a self-hosted site that you have already proven can run the same import path.
- You can connect the same Stripe account Substack uses if paid subscribers must keep access.
- Substack stays online until every required image is in the WordPress media library.
- WordPress.com Free plan import limits are approved if you are not on a paid plan.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Posts from the Substack zip | partial | critical | WordPress.com tells you to create a New export under Substack Settings → Exports, then upload that ZIP at Tools → Import → Substack after you enter the newsletter URL. | Keep the zip. Compare post counts and authors before you import subscribers. |
| Images blocked on Substack hosts | partial | critical | WordPress.com says some images fail because Substack stores them on servers that block external downloads. It tells you to keep Substack active, save the originals, and upload them under Media. | Review posts before you deactivate Substack. Re-upload broken images by hand. |
| Authors | partial | high | If the zip has multiple authors, the importer asks you to map them to WordPress users. Otherwise everything lands on the importing account. | Create WordPress users first. Check bylines after import. |
| Podcasts and public comments | partial | high | WordPress.com lists posts, images, podcasts, and public comments as in scope. Older comments can still fail, which field reports also saw. | Count comments on a sample of old and new posts. Export a Substack comment archive if comments matter. |
| Free subscribers | partial | critical | Export the entire email list from Substack Subscribers. Import it under Jetpack → Newsletter → Add subscribers → Import from Substack. Duplicates are skipped. | Record total, free, paid, and unsubscribed counts before export. |
| Paid subscribers and Stripe | partial | critical | WordPress.com asks you to connect the same Stripe account Substack uses, then map each Substack plan to a WordPress.com newsletter tier. | Connect the live Stripe account. Map every tier. Test complimentary, monthly, and annual readers. |
| WordPress.com import limits | manual | high | Free plan import is capped at 100 subscribers and earlier imports count against it. Imports over 10,000 go through manual review. Paid plans have no count cap. | Choose the plan before you import the list. |
| Theme, Sections, and Notes | lost | high | A Substack website, Sections, Notes, recommendations, and restacks do not become a WordPress theme. | Pick a theme. Rebuild landing pages and any Section as a site structure. |
| URLs | manual | critical | Substack /p/slug paths become WordPress permalinks. They will not match unless you design them to. | Decide permalinks first. Add redirects from /p/slug if you keep the domain. |
| Sending domain and deliverability | manual | critical | WordPress.com newsletter sending is a different pipeline than Substack. Field reports saw staggered delivery on the first send. | Authenticate the sending domain. Seed-test before the full list. |
| Substack analytics and restacks | lost | medium | Open rates and restacks stay on Substack. | Export stats before you leave. |
| Double billing or double sending | manual | critical | If Substack still bills or sends after WordPress takes the list, readers get two charges or two emails. | Pause Substack sending first. Confirm Stripe ownership after paid import. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Substack post zip | WordPress posts via Tools → Import → Substack | automatic | Enter the newsletter URL, then upload the zip. |
| Post title, date, and body | WordPress title, date, and content | transform | Repair missing images and embeds. |
| Substack author | WordPress user | manual | Map authors before you click Import. |
| Substack /p/slug | WordPress permalink plus a redirect | transform | Decide the permalink structure first. |
| Free subscriber CSV | Jetpack newsletter subscribers | transform | Use Import from Substack, not a generic CSV, when you also have paid readers. |
| Paid Substack plan | WordPress.com newsletter tier | transform | Connect the same Stripe account. |
| Public comments | WordPress comments | transform | Sample old posts. Some comments will not arrive. |
| Podcast enclosures | WordPress audio or podcast block | transform | Play a sample episode after import. |
| Substack theme and Notes | No destination | unsupported | Rebuild presentation and social posts separately. |
Make the move recoverable.
Create the source-of-truth backup
Keep Substack posts, subscribers, Stripe, and URLs recoverable before WordPress writes.
- Create a New export of posts and download the zip.
- Export the entire subscriber list with all columns.
- Export Stripe subscription and customer reports. Record the account ID.
- Crawl public /p/ URLs.
- Store untouched files with checksums.
Proof to capture: Zip hash, subscriber counts, Stripe account ID, and URL count in one dated manifest.
Import Substack content
Load posts, media, and authors without retiring Substack yet.
- Enter the Substack URL.
- Upload the export zip.
- Map authors.
- Review missing images while Substack is still up.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Import subscribers and paid tiers
Move free and paid readers onto Jetpack Newsletter.
- Pause Substack sending.
- Upload the subscriber CSV.
- Connect the same Stripe account and map every paid plan.
- Reconcile free, paid, and duplicate totals.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
Images disappear after you cancel Substack
WordPress.com documents that some Substack image hosts block the importer.
- Consequence
- The archive loses photos the day you shut Substack.
- Mitigation
- Re-upload before cleanup.
Stop if: A high-traffic post still hotlinks Substack.
Paid readers lose access or get billed twice
The Stripe account or tier map is wrong.
- Consequence
- Chargebacks or locked posts.
- Mitigation
- Use the live Substack Stripe account. Test each tier.
Stop if: Any active paid reader has the wrong access or a new invoice.
Free-plan import cap
WordPress.com Free allows 100 imported subscribers total.
- Consequence
- Most of the list never arrives.
- Mitigation
- Upgrade before import if the list is larger.
Stop if: The plan limit is below the live list.
First WordPress send looks like spam
A new sending pipeline hits filters.
- Consequence
- The first issue lands in spam or dribbles out for hours.
- Mitigation
- Authenticate the domain and seed-test.
Stop if: Seed delivery fails.
Do the work in this order.
- Days 1–3 · inventory
Export Substack
2–4 hours active2–3 days elapsedSubstack export waiting- Download the post zip and subscriber CSV.
- Record Stripe and public URLs.
- Choose the WordPress.com plan.
Stop / go checkpointReady to import?
Go when: Zip, list, Stripe ID, and plan limit are known.
Stop when: Paid readers exist and Stripe access is unclear.
- Days 3–5 · setup
Build the WordPress newsletter
3–6 hours active2 days elapsedTheme and domain waiting- Create the site and newsletter settings.
- Create users for authors.
- Do not send yet.
Depends on: inventory
Stop / go checkpointSafe to load posts?
Go when: The importer is available and no campaign is scheduled.
Stop when: The site cannot send mail on the chosen plan.
- Days 5–9 · import
Import posts, then subscribers
5–10 hours active2–4 days elapsedImage repairs and paid mapping waiting- Import the zip.
- Re-upload blocked images.
- Pause Substack and import subscribers.
Depends on: setup
Stop / go checkpointDid WordPress receive the publication?
Go when: Posts, images, and audience segments reconcile.
Stop when: Images still depend on Substack or paid access is wrong.
- Days 9–12 · verify
Verify URLs and seed mail
2–4 hours active1–2 days elapsedSeed delivery waiting- Test /p/ redirects if you keep the domain.
- Send to a seed list.
- Check paid and free views.
Depends on: import
Stop / go checkpointCan WordPress go public?
Go when: Blocking checks pass.
Stop when: A paid reader is locked out or seed mail fails.
- Days 12–14 · cutover
Switch the domain and first send
2–4 hours active1–2 days elapsedDNS waiting- Point the domain.
- Keep Substack readable.
- Send the first WordPress issue.
Depends on: verify
Stop / go checkpointPause Substack for good?
Go when: The first full send is clean.
Stop when: Duplicate mail or missing images appear.
Cut over with a way back.
Cutover
Make WordPress the public site and the only sender without dropping paid access.
- Pause Substack sending.
- Import the final post and subscriber delta.
- Confirm Stripe mapping still matches.
- Switch DNS after redirects are ready.
- Run blocking checks, then keep the full list unscheduled until they pass.
Proof to capture: Reconciliation sheet, Stripe account ID, image-host sample, and named approval.
Rollback
Return the domain and next send to Substack without double billing.
- Cancel WordPress campaigns.
- Restore Substack DNS.
- Do not reconnect a second Stripe owner during the incident.
- Keep the Substack zip and CSV.
Proof to capture: Substack serves the domain and is the only sender. Paid Stripe subscriptions still renew once.
- Paid access fails for an active tier
- High-traffic images still hotlink Substack
- Consent totals cannot be reconciled
- Seed delivery fails
- A blocking check cannot be fixed in two hours
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Post reconciliation | Compare the Substack zip with WordPress posts. | Every expected post exists once or has a signed exception. | Post ledger. | |
V-02Blocking | Image independence | Open image-heavy posts and inspect hosts. | No required image depends on Substack. | Image-host report. | |
V-03Blocking | Bylines | Compare multi-author posts. | Approved author map. | Author table. | |
V-04Blocking | Free and paid totals | Compare Substack export with Jetpack subscribers. | Segments match or variances are explained duplicates. | Segment table. | |
V-05Blocking | Stripe and tiers | Test monthly, annual, and complimentary readers. | Same Stripe account. Correct access. No new invoice. | Redacted Stripe and WordPress captures. | |
V-06Blocking | /p/ URLs | Request high-value Substack paths. | One 301 to the WordPress permalink if you kept the domain. | Redirect results. | |
V-07Blocking | Seed delivery | Send to controlled addresses. | From, links, and unsubscribe work. Substack is quiet. | Seed headers. | |
V-08 | Public comment sample | Compare old and new posts. | Accepted comment gaps are listed. | Comment sample. |
Remove the scaffolding safely.
Safe after: One successful full send, 24 hours of acceptable delivery, seven stable days, and a signed report.
- Archive the Substack zip, CSV, Stripe reports, and evidence.
- Re-upload leftover Substack images.
- Keep Substack readable through the retention window.
- Cancel Substack only after images and paid access are independent.
- Revoke migration users.
- Schedule the next WordPress backup and newsletter review.
When the plan met reality.
First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.
Hilda Bastian moved Living With Evidence off Substack in 2023 while the list was still small. WordPress.com had no Substack importer then, so she downloaded Substack HTML and pasted posts by hand to shrink images against the free storage cap. Subscriber CSV import under Users was smooth after she trimmed extra columns. WordPress showed fewer subscribers than she uploaded, which she blamed on about 5 percent dead addresses that Substack still counted. She posted a Substack sign-off after the first WordPress issue in case mail hit spam.
- Upload subscribers only after posts and a test subscribe path work, then send a Substack sign-off that points at the new inbox.
- Expect the WordPress count to land below the Substack export if dead addresses were still on the old list.
- A small archive can move post by post when you need to crush image size against a storage cap.
- Substack keeps broken addresses on the books, so a lower WordPress count is not always a failed import.
Alissa Grosso moved Creativity and Contentment from Substack to a WordPress.com site in April 2025. She used WordPress.com's free Substack importer for posts and the mailing list and said both transfers went smoothly. Comments on older posts did not import, which she guessed was a Substack format change. She paid $96 plus a domain she already owned, used WordPress.com's physical address on newsletter mail, and noted that comments now need a nickname and email or they show as anonymous.
- Use the official WordPress.com Substack importer for posts and subscribers, then check older comments one by one.
- Tell readers that WordPress comments need a nickname and email if you do not want a pile of anonymous replies.
- By 2025 the official importer handled posts and the list, which Hilda Bastian did not have in 2023.
- Older public comments can still fail even when posts and subscribers land cleanly.
Verify against the primary material.
Platform behavior changes. Check these sources and the review dates above before executing a production migration.
- WordPress.com: import from SubstackAccessed 2026-10-30
- WordPress.com: import Substack contentAccessed 2026-10-30
- WordPress.com: import Substack subscribersAccessed 2026-10-30
- Substack: export posts and subscriber listAccessed 2026-10-30