Webflow to Sanity migration: content, references and publishing

Moving content from Webflow to Sanity is a data migration and a publishing change. The work is not finished when records appear in the new dataset. Editors need usable fields, references need to resolve, and the site needs to render the intended content.

Gemin Pak updated Migrations

Summarize with AI

What is in this

Moving content from Webflow to Sanity is a data migration and a publishing change. The work is not finished when records appear in the new dataset. Editors need usable fields, references need to resolve, and the site needs to render the intended content.

Start with the model and a representative sample before converting the full collection.

Export the content and record its meaning

Use the CMS export or API separately from the site's code export. Record the source identifiers, field types, references, slugs and publication states. The Webflow CMS API exposes collection and item data, but the destination model still needs to be designed.

Create a field map that distinguishes direct copies from conversions. Include fields that affect search, localization or publishing even when they are not visible in the page body.

Webflow sourceProposed Sanity destinationCheckItem IDSlugAuthor referenceRich textImage URL and metadata

This is an example map, not a schema that fits every project.

Convert rich text without silently dropping content

Common paragraphs, headings, lists and links can be converted programmatically. Custom embeds, unusual markup and unsupported blocks need explicit handling rather than a blanket promise of perfect conversion.

Choose representative content early: older posts, nested lists, tables, inline images, external embeds and links to other items being migrated. Compare both the stored structure and the rendered page.

Keep an exception report. A conversion that completes while dropping a table is not a successful migration.

Preserve references with stable identifiers

Map each source ID to a predictable destination ID before importing relationships. This makes it possible to reconcile records and repeat the import without creating duplicates.

Import order depends on the method. Sanity's CLI importer temporarily weakens references and restores them after import, allowing documents to arrive in any order. A custom API import needs its own strategy for references and retries.

Test missing and circular relationships deliberately. Decide whether they should stop the import, be flagged for review or use an explicitly agreed fallback.

Move assets and update their references

Inventory the files actually used by content and the pages. Record meaningful metadata and any editorial choices such as crop or focal-point information where applicable.

Upload or import the files into the selected destination, then replace source references with destination references. Confirm that the pages no longer depend accidentally on assets you intend to retire.

Do not build the plan around an assumed date when an old CDN URL will stop working. Verify the dependencies and move the files before removing their source.

Separate importing from publishing

Preserve the intended distinction between draft, archived and published content. An import should not make private or unfinished material public by accident.

Plan how to capture edits made during the rebuild. A final delta import, a short editorial freeze or another agreed process should prevent older exports from overwriting newer work.

Handle API limits and failures explicitly. Follow the source API's current limits and retry headers rather than hardcoding a plan assumption into the migration script.

Create a field map that records decisions

A field map should explain more than which property receives a value. Add the source type, destination type, transformation, requiredness, publication behavior and validation rule. This is where the team decides whether an old field is copied, combined with another value, replaced by a reference or deliberately retired.

For a hypothetical article collection, a short summary might become a plain-text field, the author ID might become a document reference, and the body HTML might become Portable Text with approved custom blocks. A legacy campaign flag could be retained only if the new site still uses it. Record that decision so a missing value is not mistaken for an import defect later.

Keep a sample input and expected output for difficult transformations. The sample is a practical specification for the script and a review artifact for the editor. It also gives you a way to check a later conversion change without rerunning the entire migration blindly.

Use a staged import pipeline

The following sequence is a proposed migration workflow. The exact mechanics depend on whether the project uses Sanity's importer or a custom API script.

StageOutputCondition before continuing
ExtractSource records with original IDs and statesExpected collections and pages of results are present
NormalizeConsistent field values and asset inventoryUnsupported or ambiguous values are recorded
TransformDestination documents and block structuresRepresentative records match the agreed field map
LoadRecords and assets in the selected datasetFailures and retries are accounted for
ReconcileID-level report of expected and observed recordsMissing, duplicate and excluded records are explained
Render and reviewPages using the imported contentEditors and developers accept the visible result

Save intermediate artifacts where appropriate. If an import fails, the team should be able to identify whether the problem began during extraction, conversion or loading. A single script that prints only a final success message makes that investigation unnecessarily difficult.

Make reruns safe before the first full import

A migration script often needs to run more than once. The first full import reveals exceptions, the model changes, or editors continue publishing while the frontend is rebuilt. Stable document identifiers make those reruns manageable, but they are only part of the policy.

Define which fields the import owns. If an editor changes a destination record after the first import, a later run should not silently overwrite that work unless the process explicitly calls for it. Keep the authoritative editing system clear during the transition.

Record failures with enough context to retry them: source ID, destination ID, operation and reason. Avoid placing credentials or unnecessary personal data in logs. After a retry, reconcile the result against the source inventory rather than assuming that an error-free response proves the complete dataset is correct.

Deletion needs a policy too. A source item missing from the next export might have been deleted, archived, filtered out or omitted by a failed request. Do not translate absence directly into destructive deletion without determining what it means.

Review rich text with an exception pack

Choose content that exercises the actual formatting in the archive. A useful pack contains headings, nested lists, inline links, images with captions, tables, embedded media and links to other migrated records. Include old posts because older authoring practices often differ from the current template.

For each unsupported structure, choose a treatment. A table may become a supported table block. A video embed may become a structured video reference. A decorative wrapper may disappear while preserving its content. What matters is that the transformation is intentional and the renderer has a corresponding behavior.

Compare the stored output and the page. A valid block structure can still render incorrectly, and a visually acceptable page can conceal a lost link or image description. Keep the exception report available to the editor who approves the migration.

Reconcile records with arithmetic that can be explained

Counts are an efficient first check, but equal totals can hide substitutions. If a source has 100 articles and the destination has 100 records, one article might still be missing while another was duplicated.

Compare identifiers and publication states as well as totals. A useful report distinguishes expected records, deliberately excluded records, successful imports, unresolved failures and unexpected destination records. Each category should have a definition so the totals reconcile.

The same principle applies to assets and references. Count the relationships expected, then verify that they resolve to the intended records. A valid reference to the wrong author is still a content error.

Rehearse the editorial handover

Ask an editor to revise a migrated article, select an author, replace an image, preview the result and publish. Then ask them to create a new article using the same model. This reveals whether the schema supports future work as well as the imported archive.

Agree the final content checkpoint and verify the last changes before cutover. Keep source exports and migration reports for the agreed recovery period. Once the site is operating normally, document who owns schema changes and how new block types are added.

The Sanity modeling guide explains how to design those controls. The CMS choice guide helps confirm whether this editorial setup is the right destination before the import begins.

Validate the dataset and the rendered site

Sanity Studio validation rules do not automatically validate writes made through the API. Add an explicit validation step to the import workflow.

Reconcile records by ID as well as count. Check important fields, references, assets, publication states and the routes that consume them. Review the exception report before treating the migration as complete.

Finally, have an editor perform ordinary work: revise an article, replace an image, choose an author, preview and publish. The destination should be usable, not merely populated.

Discuss your CMS migration with the current collections and the publishing workflow your team needs.

Sources

Reach out and see if we are a good fit.

Get in touch

Currently booking two to four weeks out.