# How do you plan a CMS migration to Sanity, from content audit to cutover?

Reviewed by Martin Dejnicki · facts verified 25 October 2026 · canonical: https://deploi.ca/sanity/migration/cms-to-sanity

## Short answer

A content management system (CMS) migration to Sanity, from content audit to cutover, turns on three decisions: the export route, the content model mapping and a rerunnable import with stable IDs ([Sanity Learn](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project); [its migration principles](https://www.sanity.io/learn/course/refactoring-content/general-migration-principles), October 2026). A content API (application programming interface) lets the last run read live content, so any freeze stays short ([Sanity Learn](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project), October 2026).

- **Best export route:** A content API: no content freeze. File or database exports need manual steps on every run, and scraping is the fallback when no export tooling exists ([Sanity Learn, Planning a re-platforming project](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project))
- **Growth document quota:** 25,000 included, 50,000 with the add-on. The Increased quota add-on is $299 a month, as of October 2026. Growth has no document overage; the quota counts across all datasets, so a staging copy counts. Drafts count; assets don't ([Sanity, Plans that scale with you](https://www.sanity.io/pricing); [Sanity Docs, Plans and payments](https://www.sanity.io/docs/platform-management/plans-and-payments); [Sanity Docs, Technical limits](https://www.sanity.io/docs/content-lake/technical-limits))
- **Datasets on Free and Growth:** 2, so staging takes the second. Every dataset copy counts toward the plan's limit; extra datasets on Growth are $999 a month each, as of October 2026 ([Sanity Docs, Development, staging, and production environments](https://www.sanity.io/docs/content-lake/environments); [Sanity, Plans that scale with you](https://www.sanity.io/pricing))
- **Rich text converter:** @portabletext/block-tools. Headings, paragraphs and lists convert without configuration; images and other objects need custom rules; tables need a declared table type from Studio v6.6.0 ([Sanity Learn, Migrating to block content](https://www.sanity.io/learn/course/refactoring-content/migrating-to-block-content); [Sanity Docs, Configure the Portable Text Editor](https://www.sanity.io/docs/studio/portable-text-editor-configuration))

## Deploi's call

Plan a migration to Sanity around your export route and your content model, not around an importer. Start when you can rerun the import against live content and someone owns the model; until both are true, fix those gaps or move one low-risk section first.

**MIGRATE: Start planning a migration to Sanity now when**

- Your content management system (CMS) gives you an export route you can rerun, an application programming interface (API) or a repeatable export, so the final import comes from fresh content and the content freeze stays short.
- You have, or can crawl, the full list of live URLs, because the URL map and the content model start from one inventory.
- Someone owns content model decisions and editors can review the Sanity model before any import.
- Your document count, staging copy included, fits the Sanity plan you'll pay for, as of October 2026: Growth includes 25,000 documents across all datasets, or 50,000 with the $299 a month add-on.

**STAY: Stay on your current content management system for now when**

- Scraping is your only exit and most pages are presentation-built layouts, so every page becomes hand work.
- Nobody can own the content model, so you'd lift the old structure as-is, which Sanity warns recreates the same problems.
- A domain change and a redesign are already booked in the same window, because Google advises one site change at a time.
- Page speed is the only complaint and hosting or caching fixes haven't been tried.

## Which export route does your current content management system give you, and how does it shape the plan?

The export route your content management system (CMS) offers is the first fork in a migration plan to Sanity, because it decides how often you can rerun the import and how long editors stop publishing. Sanity's planning lesson names three routes: a content API (application programming interface), file or database exports, and web scraping when there's no export tooling at all ([Sanity Learn, Planning a re-platforming project](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project), October 2026).

**A rerunnable content API keeps the content freeze shortest**

| Export route | Content freeze at go-live | What you script |
| --- | --- | --- |
| Content API | Sanity's lesson says none: the last run reads live content | Paged reads, rerun until launch |
| File or database export | A fresh export before each run | Parsers for XML, SQL or JSON dumps |
| Web scraping | A fresh crawl before each run | A crawler and extraction rules per template |

The freeze and script columns are Deploi's reading of Sanity's lesson. Sources: [Sanity Learn, Planning a re-platforming project](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project); [Sanity Learn, Migrating without downtime](https://www.sanity.io/learn/course/re-platforming-to-sanity/migrating-without-downtime). As of 24 October 2026.

Sanity's MCP (Model Context Protocol) server lists guided migration paths from Contentful, WordPress, Strapi and Drupal ([Sanity blog](https://www.sanity.io/blog/sanity-remote-mcp-server-is-generally-available), October 2026), and Sanity's August 2026 migration skill is "agent-scaffolded, not fully automated" ([Sanity's August 2026 releases](https://www.sanity.io/blog/august-releases-2026)). The hub's source playbooks cover the specifics: [moving WordPress posts and plugins](https://deploi.ca/sanity/migration/wordpress-to-sanity), [mapping Contentful content types](https://deploi.ca/sanity/migration/contentful-to-sanity), [exporting from Drupal](https://deploi.ca/sanity/migration/drupal-to-sanity), [leaving Adobe Experience Manager](https://deploi.ca/sanity/migration/aem-to-sanity) and [leaving Sitecore](https://deploi.ca/sanity/migration/sitecore-to-sanity).

## How do your content types map to Sanity documents, objects and references?

Your content types map to Sanity by what each item *is*, not by the template that displays it. So Sanity's remodeling lesson stores a staff profile as a person document and a store as a location document ([Sanity Learn, remodeling lesson](https://www.sanity.io/learn/course/re-platforming-to-sanity/re-modelling-your-existing-content), October 2026).

**Most source content becomes typed documents joined by references**

| Source content | Sanity target | Decision it forces |
| --- | --- | --- |
| Template pages | Typed documents, such as person | Which templates are entities |
| Posts and pages | post and page documents | Which fields survive |
| Categories and tags | Taxonomy documents and references | Merge or keep each vocabulary |
| Authors | author documents | Which bylines need a login |
| Media library | Image and file assets | Which files are still used |
| Search metadata plugin fields | An seo object | Override and fallback rules |
| Redirect plugin rows | redirect documents | Which rows still get traffic |
| Locales | Document-level or field-level localization | Publish languages together or apart |
| Form and plugin data | A service or a schema type | Rebuild, replace or retire |

The decision column is Deploi's judgment. Sources: [Sanity Learn, Re-modelling your existing content](https://www.sanity.io/learn/course/re-platforming-to-sanity/re-modelling-your-existing-content); [Sanity Docs, Localization](https://www.sanity.io/docs/studio/localization); [Sanity Learn, SEO schema types and metadata](https://www.sanity.io/learn/course/seo-optimization/seo-schema-types-and-metadata); [Sanity Docs, Managing redirects with Sanity](https://www.sanity.io/docs/developer-guides/managing-redirects-with-sanity). As of 24 October 2026.

> **Lifting the old structure as-is**
>
> Copying your structure as-is "opens the door to recreating your existing problems, just on a new stack", Sanity warns ([Sanity Learn](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project), October 2026). Remodeling against lift and shift weighs the trade.

## How does rich text from any CMS become Portable Text?

Rich text from any content management system (CMS) becomes Portable Text, Sanity's JSON format for rich text and block content, through a conversion script built on `@portabletext/block-tools`. The package converts headings, paragraphs and lists without configuration; images and other complex objects need custom rules that parse them out of the HTML ([Sanity Learn, Migrating to block content](https://www.sanity.io/learn/course/refactoring-content/migrating-to-block-content), October 2026).

The conversion cost follows the source. Sanity says the job is "more difficult the more presentation-focused your source content is" ([Sanity Learn](https://www.sanity.io/learn/course/refactoring-content/migrating-to-block-content)), so pages built from layout blocks cost more to convert than articles written in a plain editor. Log every HTML element your rules don't handle, because each one is a schema decision (Deploi's judgment).

Tables don't block the move. The Portable Text Editor has built-in table editing from Studio v6.6.0; it is disabled by default and needs a `table` schema type you declare ([Sanity Docs, Configure the Portable Text Editor](https://www.sanity.io/docs/studio/portable-text-editor-configuration), October 2026; [Sanity's August 2026 releases](https://www.sanity.io/blog/august-releases-2026)). A migrated HTML table still needs a conversion rule that fills your table type (Deploi's judgment). Each source playbook covers its own conversion, and how Portable Text stores rich text explains the format.

## What content problems should you plan for before writing the migration script?

Plan for content entropy, the inconsistency a content management system (CMS) collects when it lacks validation. Sanity's planning lesson says to expect "broken links, references to media, images, and users that no longer exist, empty paragraphs, lines with whitespace, and mismatched encoding" ([Sanity Learn, Planning a re-platforming project](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project), October 2026). Three rules for the migration script follow from Sanity's courses:

- **Fail loudly.** Sanity suggests you `throw` on errors so scripts don't import invalid data, because logging alone may not help ([Sanity Learn, General migration principles](https://www.sanity.io/learn/course/refactoring-content/general-migration-principles), October 2026).
- **Validate in the script.** Schema validation rules run only in Sanity Studio, so application programming interface (API) writes and imports aren't checked against them ([Sanity Docs, Import data](https://www.sanity.io/docs/content-lake/importing-data), October 2026). Sanity suggests a runtime validator such as Zod, then `sanity documents validate` once content lands ([Sanity Learn, Migrating without downtime](https://www.sanity.io/learn/course/re-platforming-to-sanity/migrating-without-downtime)).
- **Leave dead content behind.** Sanity's lesson ranks content by its role and its analytics and moves only what still serves ([Sanity Learn](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project)). A content audit before the move builds that list.

## How many Sanity documents will a migration use once staging is counted?

A migration uses the documents in every dataset added together, staging included, because Sanity's document quota applies across all datasets in a project ([Sanity pricing](https://www.sanity.io/pricing); [Sanity Docs, Plans and payments](https://www.sanity.io/docs/platform-management/plans-and-payments), October 2026). Growth includes 25,000 documents and allows no document overage; the $299 a month Increased quota add-on raises the total to 50,000, Growth's ceiling, and past that the path is Enterprise, as of October 2026 ([Sanity pricing](https://www.sanity.io/pricing); [Technical limits](https://www.sanity.io/docs/content-lake/technical-limits)).

Three rules decide your total:

- **Staging doubles the count.** Free and Growth include 2 datasets, and every dataset copy counts toward that limit ([Sanity Docs, Development, staging, and production environments](https://www.sanity.io/docs/content-lake/environments), October 2026), so a full staging copy takes the second dataset and adds a second set of documents.
- **Drafts count.** A draft with unpublished changes is a separate document; image and file assets don't count ([Sanity Docs, Plans and payments](https://www.sanity.io/docs/platform-management/plans-and-payments); [Technical limits](https://www.sanity.io/docs/content-lake/technical-limits)).
- **Remodeling raises the count.** Splitting template pages into typed documents adds documents (Deploi's judgment), so count after the model review.

[What Sanity's Free and Growth plans include](https://deploi.ca/sanity/faq/is-sanity-free) and what counts as a Sanity document go further.

## What happens to users, roles, editorial workflow and plugins in a move to Sanity?

Each user and plugin in your old content management system (CMS) needs a named home in Sanity, because roles, workflow and plugin features don't arrive with the exported content (Deploi's judgment). Editors become project members with roles, bylines become author documents, approval steps need their own plan, and plugins become schema types, front-end code or a separate service.

- **Roles.** Free has Administrator and Viewer, Growth has five fixed roles, and custom roles are an Enterprise feature, as of October 2026 ([Sanity Docs, Roles and permissions](https://www.sanity.io/docs/content-lake/roles-concepts); [Sanity pricing](https://www.sanity.io/pricing), October 2026). Map each old role to its closest Growth role and list the gaps; what each Sanity role can do has the matrix.
- **Workflow.** Sanity Workflows is in early access with pre-1.0 packages, as of October 2026, so don't count it as a finished replacement for your current moderation steps ([Sanity Docs, Workflows](https://www.sanity.io/docs/workflows/introduction); [How early access works](https://www.sanity.io/docs/workflows/prerelease), October 2026).
- **Plugins.** Search engine optimization (SEO) fields move to an `seo` object with an override and a fallback ([Sanity Learn, SEO schema types and metadata](https://www.sanity.io/learn/course/seo-optimization/seo-schema-types-and-metadata)), and redirects become documents ([Sanity Docs, Managing redirects with Sanity](https://www.sanity.io/docs/developer-guides/managing-redirects-with-sanity)). Sanity's Webflow course says forms need "a full replacement" ([Sanity Learn, Set up forms, redirects, and sitemap](https://www.sanity.io/learn/course/migrating-content-from-webflow-to-sanity/forms-redirects-sitemap), October 2026).
- **Training.** Sanity says training is "*absolutely* required for content creators" ([Sanity Learn](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project)), so put editors in the model review.

## What is the step-by-step plan for a CMS migration to Sanity, and who owns each step?

A content management system (CMS) migration to Sanity runs in eight steps, and the script reruns from step four to seven. Sanity's course says migration scripts "usually have to be run multiple times", so IDs derived from the source let a rerun update documents, not duplicate them ([Sanity Learn, General migration principles](https://www.sanity.io/learn/course/refactoring-content/general-migration-principles), October 2026); `sanity datasets import` needs `--replace` for that.

**Planning a CMS migration to Sanity**

1. **Inventory and crawl.** Count each content type and crawl every live URL. Owner: content and search leads.
1. **Prove the export route.** Pull ten real items through it, the messiest included. Owner: developer.
1. **Review the model with editors.** Agree types, references and what to retire. Owner: content lead.
1. **Write an idempotent script.** Derive each document ID from its source ID and throw on bad data. Owner: developer.
1. **Import safely.** Load staging first unless nothing public reads the dataset yet; [safe imports into Sanity](https://deploi.ca/sanity/migration/cms-to-sanity/safe-import) covers flags, webhooks and rollback. Owner: developer.
1. **Verify.** Compare counts per type, validate documents and test every old URL against [the search and redirect plan](https://deploi.ca/sanity/migration/cms-to-sanity/seo-preservation). Owner: developer and search lead.
1. **Cut over.** Run the last import from fresh content and switch, following [cutover and rollback](https://deploi.ca/sanity/migration/cms-to-sanity/cutover-and-rollback). Owner: developer.
1. **Sign off and monitor.** Close [the migration checklist](https://deploi.ca/sanity/migration/cms-to-sanity/migration-checklist) and watch errors and search traffic. Owner: project owner and search lead.

## When should you not start a migration to Sanity yet?

Don't start a migration to Sanity until your plan has room to rehearse the import and your export route has worked on real items, because both gaps surface after the scripting has begun (Deploi's judgment). Booked site changes are the other hold: Google's site move guidance says to plan changes "one after the other, not everything at the same time", naming a content management system (CMS) change among its examples ([Google Search Central, Site Moves and Migrations](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes), October 2026). Redesigning and replatforming together weighs that choice.

> **Hold the migration to Sanity when**
>
> - Both of your plan's datasets are in use and no budget covers another, so there's nowhere to rehearse; an extra Growth dataset is $999 a month, as of October 2026.
> - You're on Free and imported content can't be public yet, because Free's two datasets are public only, as of October 2026 ([Sanity pricing](https://www.sanity.io/pricing); [Sanity Docs, multi-tenancy guide](https://www.sanity.io/docs/developer-guides/multi-tenancy-implementation)).
> - Your count, staging copy included, passes 50,000 documents and no Enterprise quote is budgeted, as of October 2026.
> - No real items have been through the export route yet, so the plan rests on a guess.

If only part of the site is ready, start there. Sanity's remodeling lesson suggests low-risk content first, such as terms of service or support pages, then expanding the rollout ([Sanity Learn, remodeling lesson](https://www.sanity.io/learn/course/re-platforming-to-sanity/re-modelling-your-existing-content), October 2026).

## Deploi's point of view

**Where we disagree.** The common pitch treats a CMS migration as an export and an import: pick a tool, move the content, switch the domain. The work that sets the cost sits elsewhere. The export route decides how often you can rerun, the model mapping decides how much content gets reshaped, and plugins turn into separate builds. A one-to-one copy of pages moves the old CMS's problems onto Sanity, which Sanity's own course warns against.

**What we've seen.** Deploi has moved its own Sanity content with the discipline a migration needs. In September 2026 Deploi moved its FAQ content and chatbot settings from a standalone Sanity project into a shared one, with a dry-run cutover script and an import that never overwrote editors' versions. The same month, scripts that change nothing unless told to apply moved 256 live FAQ answers on deploi.ca to shorter URLs, skipping any document edited since the snapshot. Both were changes inside Sanity.

**What we'd tell you to do first.** Before any schema work, get three things: a count of every content type, a crawl of every live URL, and ten real items pulled through your export route, the messiest included. The counts pick the plan, the crawl sizes the redirect work, and the ten items show which export route you actually have.

## When this answer changes

- Sanity changes the Growth document quota, the $299 Increased quota add-on or the 50,000 ceiling
- Sanity changes the datasets included on Free and Growth or the $999 extra dataset price
- Sanity rewrites or retires its re-platforming or refactoring courses
- Sanity ships an official importer for a source CMS or changes the MCP server's migration paths
- @portabletext/block-tools changes its default conversions, or Portable Text tables are enabled by default
- Sanity Workflows leaves early access

## Follow-up questions

- [CMS migration checklist](https://deploi.ca/sanity/migration/cms-to-sanity/migration-checklist)
- [Keeping SEO through a move to Sanity](https://deploi.ca/sanity/migration/cms-to-sanity/seo-preservation)
- [Safe imports into Sanity](https://deploi.ca/sanity/migration/cms-to-sanity/safe-import)
- [Cutover and rollback](https://deploi.ca/sanity/migration/cms-to-sanity/cutover-and-rollback)

## Ready to plan your move to Sanity?

Contact us today to talk through your export route, content model and URL inventory before any import script is written. [Contact us](https://deploi.ca/contact)

## Sources

1. [Sanity Learn, Planning a re-platforming project](https://www.sanity.io/learn/course/re-platforming-to-sanity/planning-a-re-platforming-project), checked 24 October 2026
2. [Sanity Learn, Re-modelling your existing content](https://www.sanity.io/learn/course/re-platforming-to-sanity/re-modelling-your-existing-content), checked 24 October 2026
3. [Sanity Learn, Migrating without downtime](https://www.sanity.io/learn/course/re-platforming-to-sanity/migrating-without-downtime), checked 24 October 2026
4. [Sanity Learn, General migration principles](https://www.sanity.io/learn/course/refactoring-content/general-migration-principles), checked 24 October 2026
5. [Sanity Learn, Migrating to block content](https://www.sanity.io/learn/course/refactoring-content/migrating-to-block-content), checked 24 October 2026
6. [Sanity Docs, Import data](https://www.sanity.io/docs/content-lake/importing-data), checked 24 October 2026
7. [Sanity Docs, Plans and payments](https://www.sanity.io/docs/platform-management/plans-and-payments), checked 24 October 2026
8. [Sanity, Plans that scale with you](https://www.sanity.io/pricing), checked 24 October 2026
9. [Sanity Docs, Roles and permissions](https://www.sanity.io/docs/content-lake/roles-concepts), checked 24 October 2026
10. [Sanity Docs, Development, staging, and production environments](https://www.sanity.io/docs/content-lake/environments), checked 24 October 2026
11. [Sanity Docs, Technical limits](https://www.sanity.io/docs/content-lake/technical-limits), checked 24 October 2026
12. [Sanity Docs, Configure the Portable Text Editor](https://www.sanity.io/docs/studio/portable-text-editor-configuration), checked 24 October 2026
13. [Sanity, What’s new in August: inline tables, functions calling functions, and visual editing without React](https://www.sanity.io/blog/august-releases-2026), checked 24 October 2026
14. [Sanity Docs, Localization](https://www.sanity.io/docs/studio/localization), checked 24 October 2026
15. [Sanity Learn, SEO schema types and metadata](https://www.sanity.io/learn/course/seo-optimization/seo-schema-types-and-metadata), checked 24 October 2026
16. [Sanity Docs, Managing redirects with Sanity](https://www.sanity.io/docs/developer-guides/managing-redirects-with-sanity), checked 24 October 2026
17. [Sanity Learn, Set up forms, redirects, and sitemap](https://www.sanity.io/learn/course/migrating-content-from-webflow-to-sanity/forms-redirects-sitemap), checked 24 October 2026
18. [Sanity, You’ll need a CMS eventually. Let your agent set it up.](https://www.sanity.io/blog/sanity-remote-mcp-server-is-generally-available), checked 24 October 2026
19. [Google Search Central, Site Moves and Migrations](https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes), checked 24 October 2026
20. [Sanity Docs, Workflows](https://www.sanity.io/docs/workflows/introduction), checked 24 October 2026
21. [Sanity Docs, How early access works](https://www.sanity.io/docs/workflows/prerelease), checked 24 October 2026
22. [Sanity Docs, How to implement multi-tenancy with Sanity](https://www.sanity.io/docs/developer-guides/multi-tenancy-implementation), checked 24 October 2026
