Contentful to Sanity Migration Checklist for Next.js Sites

In Brief
Treat the migration as a controlled sequence rather than an export‑and‑import job. Audit the Contentful model, decide what should not be copied, map references and rich text, migrate assets, rebuild the front‑end data layer, restore preview, protect metadata, and redirects, then test with real content before launch.
A Contentful to Sanity migration can look deceptively simple from a distance. Export entries, transform them, import documents, update queries, ship the new CMS. That version of the story is tidy because it ignores most of the risk.
The commercial trigger is often real. Contentful has become expensive enough, and restrictive enough, that teams can reach the point where continuing to absorb the platform cost makes less sense than paying once for a controlled migration. I have seen many clients outgrow Contentful in exactly that way. The CMS still works, but the cost and constraints no longer match the site's shape, publishing needs, or ownership model.
The import is only the visible part of the work. The real migration is the contract between the old Contentful model, the new Sanity schema, the Next.js front end, and the editorial and SEO behaviour that has to survive the move.
If a migration preserves entries but loses meaning, preview confidence, internal links, canonical logic, structured data, or route behaviour, the site has not really migrated cleanly. It has just moved the problem into a new system.
If you need the failure modes before the checklist, read the companion piece on Contentful to Sanity migration risks for Next.js sites. This article is the planning pass: what to check before the first test import, what to prove before cutover, and what should be watched after launch.
For teams already considering a move, my Contentful to Sanity Migration service is built around that wider risk. This checklist is the same idea in article form: plan the migration as a controlled release, not as a blind export and import.
Start with a Content Model Audit
Before writing a Sanity schema, audit the Contentful model as it exists today.
List every content type, field, validation rule, reference, asset field, rich text field, slug field, metadata field, locale setting, and preview behaviour. Then look at how those pieces are actually used by the Next.js application. Some fields may drive rendering. Some may exist only because an older template needed them. Some may be populated in the CMS but ignored by the front end.
The useful audit asks:
- Which content types represent real editorial concepts?
- Which fields are required by rendering, SEO, schema, navigation, or tracking?
- Which references are essential, optional, duplicated, or stale?
- Which rich text blocks contain embedded entries or custom rendering?
- Which slugs and URLs are public contracts?
- Which metadata fields feed titles, descriptions, Open Graph, canonicals,
noindexrules, schema, or sitemaps? - Which preview behaviours do editors rely on before publishing?
Do not treat the Contentful model as automatically correct just because the current site depends on it. The audit should separate editorial meaning from implementation history.
Decide What Should Not Be Copied
A weak migration recreates Contentful inside Sanity.
That usually means copying every content type, every field, every old naming convention, and every awkward workaround into a new schema. The result is familiar, but not better. Editors still fight the same abstractions. Developers still write defensive rendering code around unclear data. The new CMS inherits the old confusion.
Make deliberate decisions before schema work starts. Remove obsolete fields. Consolidate duplicated models where the distinction no longer helps editors. Keep separate models where the distinction carries real meaning. Rename fields when the old names describe implementation details rather than content purpose.
This is also where cost and restriction should influence the design without taking over the design. If the old Contentful setup became expensive because the site accumulated content types, environments, workflows, locales, users, or usage patterns that no longer fit neatly, do not recreate those pressures by accident. Sanity should carry the content model the site now needs, not every workaround that grew around the previous pricing and product constraints.
The aim is not to make the model clever. It is to preserve editorial meaning whilst removing the accidental shape of the old implementation.
Map Contentful Content Types to Sanity Documents
Sanity gives you documents, objects, references, arrays, validation rules, field groups, previews, and Studio configuration. That does not mean every Contentful content type should become a Sanity document.
Some Contentful entries should become top‑level documents because editors search for, publish, and route them independently. Articles, landing pages, case studies, services, authors, and reusable entities often fit that pattern.
Other entries may be better as objects inside a document. A small callout, statistics block, or one‑off section may not need its own publishable identity. If editors never manage it independently, making it a separate document can add noise.
The mapping should decide:
- document types and their slugs
- nested object types
- reusable references
- Portable Text blocks and custom annotations
- validation rules
- field names and groups
- Studio preview labels
- editorial ordering and navigation
This is where headless architecture consulting matters. CMS modelling is not only a data exercise. It shapes what editors can understand, what developers can query, and what the public site can render reliably.
Handle References Deliberately
References are where many migrations become untidy.
Contentful entry references may point to pages, authors, reusable modules, shared page sections, media wrappers, taxonomy entries, or old content that is no longer used. Some references are circular. Some are optional in the CMS but treated as required by the front end. Some are broken because linked entries were unpublished, deleted, archived, or environment‑specific.
Plan reference migration before the import script runs.
You need stable mapping between Contentful entry IDs and Sanity document IDs. You need import ordering for documents that depend on each other. You need a policy for broken references: repair, skip, replace, or fail the migration. You also need validation after import, because a successful API response does not prove that the graph is usable.
After the test import, query for missing references, unexpected nulls, orphaned documents, duplicate slugs, and documents that exist in Sanity but cannot be reached from any route or editorial workflow.
Treat Rich Text as a Migration Risk
Rich text is not just body copy.
In Contentful, rich text can contain paragraphs, headings, marks, hyperlinks, embedded entries, embedded assets, inline entries, and content‑type‑specific rendering decisions. In Sanity, Portable Text gives you a different model for blocks, spans, marks, annotations, and custom object types.
A one‑to‑one conversion may be possible for simple paragraphs and headings. It becomes more risky when articles contain embedded code examples, custom panels, reusable calls to action, internal links, media, tables, or page‑specific modules.
Before migration, inspect real rich text fields, not only the schema. Check the oldest articles, the highest‑traffic pages, and the content types editors have stretched furthest. Then decide how each Contentful node type maps to Portable Text or to a separate field.
Rendering parity in Next.js matters here. A converted block is not good enough until the public route renders the same meaning, headings, links, media, and accessible text as the old page. If the current system already has preview issues, this is a good moment to read the draft on fixing Contentful preview in Next.js, because preview trust is usually tested hardest during migration.
Preserve Slugs, URLs, and Redirects
URL changes are expensive unless they are intentional.
Create an inventory of existing public URLs before the migration. Include articles, services, landing pages, case studies, category pages, paginated routes, redirects, and any legacy paths still receiving traffic or links. Then map each URL to its target after the Sanity migration.
For each route, decide:
- Does the URL stay exactly the same?
- Does the slug field move into Sanity?
- Does the route structure change?
- Is a redirect needed?
- Does the canonical URL match the intended destination?
- Do internal links still point at the canonical route?
- Should any old URL return 404 or 410 rather than redirect?
Avoid URL churn unless there is a clear reason. A CMS migration is already enough change for search engines and users to process. Changing the route estate at the same time raises the risk.
If a wider platform move is happening too, connect this work with Migrations to Next.js and the article on traffic drops after a replatform. Redirects are not just status codes. They preserve intent, internal equity, and crawl paths.
Protect Metadata and Structured Data
Metadata often looks small in a CMS export, but it carries a lot of public meaning.
Titles, meta descriptions, Open Graph titles, Open Graph descriptions, social images, canonicals, robots directives, schema fields, breadcrumb labels, sitemap inclusion flags, and related content all need explicit handling. Do not assume the old fields map neatly into the new schema.
Check where metadata is currently generated. Some values may come directly from Contentful. Some may be derived in Next.js. Some may fall back to page titles, global defaults, category names, or hard‑coded templates.
For each important template, compare the rendered HTML before and after migration:
<title>- meta description
- canonical link
- robots directives
- Open Graph and Twitter metadata
- JSON‑LD structured data
- visible headings
- internal links
- sitemap inclusion
My article on the business case for structured data is useful background here. Schema is only valuable when it matches visible content and the page's real entity relationships.
Rebuild Preview and Draft Behaviour
Editors need confidence before publishing.
A Contentful to Sanity migration is not complete if the public page renders but preview becomes unreliable. Editors need to see draft content, published content, validation messages, missing required fields, and route behaviour before they press publish.
Define the preview contract early:
- Which Sanity document types can be previewed directly?
- Which supporting documents need a parent page preview?
- Which dataset and environment does preview use?
- How does the preview URL validate content and route intent?
- Does the Next.js site use Draft Mode or an equivalent existing implementation?
- How are unpublished references handled?
- What happens when a document has no slug yet?
Sanity Studio can be tailored around editorial workflow, but tailoring should support confidence rather than novelty. A good preview flow is plain, fast enough to use, and honest when something cannot be previewed directly.
Update the Next.js Data Layer
The front end must stop thinking in Contentful shapes.
That means updating queries, data fetching, transformation helpers, TypeScript types, static generation, revalidation, preview fetching, error handling, and fallback behaviour. Do not hide the migration behind a compatibility layer for longer than necessary. Temporary adapters can be useful during the move, but permanent Contentful‑shaped abstractions can make the Sanity model harder to use properly.
Check the routes that matter most:
- static article and service routes
- dynamic route generation
- page composition
- preview routes
- sitemap generation
- related content surfaces
- image handling
- missing content behaviour
- cache and revalidation paths
For a Next.js site, CMS migration and rendering strategy are tied together. If the site relies on static generation, incremental regeneration, build‑time fetches, or preview‑specific data paths, all of those paths need to be tested against Sanity data.
Run a Full Test Migration
Do not make the first real migration the launch migration.
Import into a safe Sanity dataset or environment. Then compare the old and new systems before any public cutover. Count entries, documents, assets, routes, templates, references, slugs, redirects, missing fields, and rendered pages. Open real pages in the browser, not just CMS entries in a dashboard.
A useful test migration checks:
- page counts by template
- URL parity
- slug uniqueness
- reference integrity
- asset availability and alt text
- rich text rendering
- metadata and structured data
- preview behaviour
- editor publishing flow
- search‑critical templates
- error handling for missing or malformed content
The point is to fix the migration script before launch, not to fix hundreds of documents manually afterwards.
Run a Final Data Migration Before Launch
The final migration needs a cutover plan.
Decide whether the team needs a content freeze, a delta migration, or a clear rule for changes made between test migration and launch. If editors keep publishing in Contentful after the test import, those changes need to be captured. Otherwise the launch can silently lose recent work.
Before launch, re‑run redirect validation, sitemap checks, metadata checks, preview checks, and route smoke tests. Keep rollback planning practical. If the new Sanity‑backed site has to be rolled back, which content changes are lost, which redirects change, and who makes the call?
That sounds cautious because it is. CMS migrations fail most expensively when nobody knows which system is the source of truth during cutover.
Check the Site After Launch
Launch is not the finish line.
After the Sanity‑backed site is live, crawl the important routes. Check indexability, redirects, canonical URLs, metadata, structured data, rendered HTML, internal links, sitemap output, preview routes, logs, and errors. Watch Search Console for changes in coverage, crawl behaviour, query groups, and important landing pages.
Also check the editorial system under normal use. Can editors create, preview, validate, and publish the content types that matter? Are required fields clear? Are broken references prevented rather than discovered after publication? Does the Studio structure make sense after a week of real work?
A migration that only passes a launch checklist can still fail the people who have to use it every day.
Wrapping Up
A Contentful to Sanity migration is not complete when the content imports successfully.
The safer migration preserves meaning, references, editorial workflow, preview behaviour, front‑end rendering, metadata, redirects, structured data, and search‑critical output. It also removes legacy CMS shape where that shape no longer helps.
Treat the work as a controlled release. Audit first, model deliberately, test the migration, validate the rendered site, and keep the cutover boring.
Key Takeaways
- Audit the existing Contentful model before writing the Sanity schema.
- Preserve editorial meaning, not every legacy field and workaround.
- Treat references, rich text, preview, metadata, and URLs as migration risks.
- Validate rendered Next.js output, not only CMS import success.
- Plan final cutover and post‑launch checks before the first public switch.