A clean export can still be a broken migration
A CMS export can move every record successfully and still produce a failed headless migration because relationships can flatten, embedded URLs can keep pointing at the old system, and editorial actions can disappear even when the exported data looks complete. A WordPress post shows the problem clearly: its title, permissive body, metadata, shortcodes, and embedded blocks contain structure that WordPress itself resolves during rendering. Moving the stored values does not reproduce that behavior elsewhere.
Because stored values are only part of the work, page count is a weak measure of migration scope. A flat content type without locales might move in days, while a deeply referenced, multi-locale model containing a dozen content types can take several months to set up. The planning range can stretch from a “two-week job” to a “two-quarter one” because the key question is what must be reconstructed before records can safely enter the target.
That reconstruction makes implicit CMS behavior explicit. A shortcode may encode a gallery, an ID may represent a relationship, and a block may rely on a theme to produce meaningful output. Headless systems tend to express those decisions as fields, validated formats, references, locales, assets, and publication states. Migration gets harder as the source behavior and target model diverge.
Scope by bounded content type and measure the mismatch inside it
To control that mismatch, use a bounded content type: one content model that can be mapped, migrated, validated, and proven before the team advances to another. Start by exporting the source content model before writing migration code. For every field, compare its source behavior with the target platform’s field library and count three outcomes: direct matches, values requiring transformation, and fields with no target equivalent. Those counts reveal work that record volume cannot.
Field comparison then leads to the structures around those fields. Search for shortcode patterns, measure the depth of internal references, determine how translations are represented, inventory absolute asset URLs embedded in content, and record what editors actually do each day. Scheduling, bulk editing, preview, draft handling, and publication belong in scope because the destination must support the operations that make migrated content usable.
Those findings are a more useful estimating input than pages or database rows. One rough rule of thumb is two to four weeks per bounded content type for mapping, validation, and QA, with reference and locale complexity adding work. Treat the range as a planning heuristic: the audit of each bounded type determines where its work falls.
Because the destination shapes that audit, perform it before locking the target platform. Contentful, Strapi, and Storyblok make different assumptions about localization, references, publication state, and supporting objects, so the same source model can require different transformations on each destination. An internal “content-modelling guide” can help while the destination schema is designed. Platform selection and migration design meet at the field model because the chosen system determines which source structures can carry over directly and which must change.
The field-level comparison also explains why bounded types with similar entry counts can demand very different effort. Two types can have radically different reference graphs, locale structures, and rendering dependencies even when their record counts match. Scope and sequence the work by bounded type, then use the mismatches inside each type to determine its actual size.
A project in mind?
Schedule a 30-minute meeting with us.
Senior experts helping you move faster across product, engineering, cloud & AI.
Make field semantics and render-time behavior explicit before import
Once a bounded type is under inspection, the first concrete failures often appear where permissive source fields meet strict target validation. WordPress can hold nested HTML, inline styling, arbitrary long-form values, and shortcodes in content whose behavior is partly determined during rendering. A structured target field accepts a narrower model, so an attempted write can return a 422 validation error or a schema exception even though the export appears complete.
Contentful illustrates that boundary through field types and content-type validation, which its management API enforces when entries are created or updated. Contentful is a commercial CMS vendor and benefits when teams adopt and migrate to its platform, so its documentation describes the behavior of a product it sells. Its rich text is a structured document rather than an arbitrary HTML container: a with inline CSS can lose its styling, a raw iframe can produce “unrecognized node type,” and can survive as inert text. The bytes may persist while the behavior they once triggered disappears.
The WordPress REST API exposes raw and rendered post content, but neither representation automatically converts the shortcode’s arguments into a target CMS relationship. Shortcode and render mapping therefore belong upstream in the content model.
Once the shortcode dependency is explicit, each mismatch can get a specific treatment. HTML destined for structured rich text has to be converted into the target document format, while known shortcodes need lookup tables that map their behavior to target components or references. Transformations with no safe mapping go to manual review. Galleries and related-post blocks can then become explicit content types and relationships instead of instructions understood only by a legacy renderer.
Strapi exposes a related problem through typing decisions. A source field labelled as short text may contain material that functions as rich text, while a long-form WordPress custom field may have accumulated values without meaningful validation. Strapi’s content-type builder requires typed structures, and relationships require cardinality, meaning whether one record can connect to one or many others, such as one-to-one, one-to-many, or many-to-many. Strapi is also a commercial CMS vendor, so its product model reflects capabilities it benefits from teams adopting; a script can populate a selected relationship, but a person still has to decide which cardinality represents the content correctly.
Those decisions show what schema translation changes. Source material has to be re-expressed as typed fields, validated formats, and explicit references whose behavior survives independently of a theme. Strict validation creates migration failures because it exposes assumptions that a permissive source system allowed to remain unstated. Resolving those assumptions during mapping avoids discovering them later in a production renderer.
The source CMS also affects how much structure is already explicit. WordPress is particularly exposed because shortcodes and theme-dependent constructs can hide substantial structure inside otherwise ordinary content. Drupal has a relative advantage because paragraphs and entity-reference fields already express relationships in forms closer to those expected by Contentful, Strapi, and Storyblok, although Drupal can still contain rendering-dependent inline images and view-embed tokens. Both systems therefore need an audit for rendering-dependent constructs before cutover.
References and locales turn individual fields into migration graphs
After fields become explicit references, migration scope extends beyond the entry being moved. An article can reference an author biography, three related posts, and a product card; those objects can have their own references, producing a graph four or five entries deep. Measuring internal-reference depth during the audit exposes these dependencies before an apparently self-contained content type pulls other models into its migration.
That graph can extend well beyond the depth a team wants to manage as one migration unit. Contentful’s linked-entry documentation says its Content Delivery API include mechanism can resolve linked references up to 10 levels deep. Support for that depth does not make a deeply connected model easy to migrate, because every level adds ordering, validation, and publication dependencies. A practical recommendation is to treat graphs crossing roughly three or four levels as candidates for separation into their own bounded types, which can be mapped and proven before the larger graph depends on them.
Those dependencies also constrain import order. Contentful’s management API validates reference fields against the content types permitted by the schema, so destination models need to exist before entries that refer to them are imported. Publication state adds another dependency because Contentful’s Content Delivery API does not return unpublished entries. An otherwise valid migrated reference can disappear from delivery when its dependency remains a draft, so sequencing must coordinate published states as well as IDs.
Localization adds a second graph decision before field migration begins. First determine whether the source stores translations as separate records or as localized values on a single record. Separate posts connected through a shared slug or plugin table fit a locale-per-entry architecture, where each language version is its own entry. A locale-per-field destination stores language variants together, so migration must find sibling translations and merge them into one entry before mapping their fields.
The reverse transformation changes the record graph in the opposite direction. If the source stores sibling localized fields on a single record and the destination uses Strapi’s i18n plugin, those values have to become separate localized entries connected through Strapi’s localization relation. Strapi’s approach is locale-per-entry, so references address entries belonging to particular locales. Translation architecture therefore changes both the number of destination entries and the shape of their relationships.
Contentful’s locale-per-field design is the alternative: localized values can sit side by side within fields on one entry, with references resolved through the locale used at delivery. Contentful and Strapi compete for CMS adoption and each benefits commercially from use of its own architecture, so these product models should be evaluated as destination constraints rather than neutral recommendations from either vendor. A missing sibling, bad localization relation, or incompatible reference is a translation defect that should be resolved before the team advances to the next bounded type.
Together, reference depth and localization determine migration prerequisites. A bounded content type remains the execution boundary, but relationships can require other types to move first, while localization can require source records to merge or split. Those transformations need to be fixed before import order can be reliable.
Assets, supporting objects, and editor workflows are content dependencies too
Once entry relationships are mapped, asset addresses can still tie apparently migrated content to the old system. WordPress commonly stores absolute media URLs inside post content, so a straight export carries those addresses into the new CMS. Contentful can serve assets from images.ctfassets.net, Storyblok from a.storyblok.com, while Strapi can use self-hosted upload paths. A migrated entry must point to the destination address so it can survive retirement of the old location.
That requirement makes an old-to-new asset ID map part of the migration. As files move, embedded URLs in rich text or structured content can be rewritten from that map through a transformation or find-and-replace pass. Changed page and asset paths also require permanent 301 mappings. Google Search Central’s redirect guidance identifies 301 as the appropriate HTTP status for a permanent URL change.
Those redirects connect asset work to an SEO-safe website migration. A page can contain correctly imported text while still serving broken images, and an old URL already known to search engines can stop resolving to its replacement. Asset migration therefore produces two distinct results: working references inside the new content and permanent mappings from previously public addresses.
Beyond assets, some dependencies exist as separate platform objects. Storyblok datasources, for example, are reusable option lists stored separately from stories. Storyblok’s management API handles stories and datasources as distinct concerns, and its space-migration documentation covers stories while datasources require their own pass. Storyblok is a commercial CMS vendor and benefits from adoption of this platform model, but the migration consequence is concrete: moving stories without their datasources leaves dropdown and select fields without the option sets they require.
Platform objects then lead to editor behavior, another dependency that an entry export cannot capture. In a traditional CMS, an editor may draft, preview, schedule, edit in bulk, and publish through behavior bundled into the platform. Headless preview requires a frontend capable of rendering unpublished material, while draft and publication workflows vary among platforms. Content can therefore arrive correctly while editors lose the process needed to prepare it for publication.
For that reason, inventory workflow at the level of actual editor actions. Confirm a destination path for scheduling, bulk editing, preview, draft and publish behavior, and every step between content creation and release. Storyblok defines three workflow stages, Drafting, Reviewing, and Ready to Publish; Contentful supports simultaneous editing with rollbacks and comments; Strapi separates Draft and Published states. Because these three vendors compete for CMS adoption and benefit commercially from use of their products, their workflow capabilities should be treated as destination-specific facts to verify against the editorial process being migrated.
Making editor actions explicit has the same purpose as mapping shortcode behavior. The migration preserves an operational model alongside stored values, so functions previously supplied by the old CMS have to be deliberately reconstructed across the destination CMS and its frontend. That work belongs in scope before production cutover.
Pilot one bounded type end to end, then prove it under parallel operation
With the dependencies mapped, begin with a deliberately simple bounded type. A landing page or FAQ is a better pilot than an article full of shortcodes and cross-references when it has few references, no locale complexity, and low editorial traffic. Migrate that type end to end, including content, assets, references, and the workflow editors will use. The clean export from the start of the migration is useful input, but a successful API import still does not prove that the migrated type works.
The pilot provides stronger evidence when it remains live while the source CMS continues serving the rest of the site. During this parallel run, meaning a period when both systems operate at the same time, separate routes or subdomains can expose the new model to real use without forcing every other content type across with it. Real use can expose unresolved references, asset URLs returning 404 responses, and locale fallbacks that differ from the old CMS. These failures are difficult to establish from a static import result alone.
Because the goal is to exercise real behavior, editorial activity should determine the observation period. The planning heuristic of two to four weeks per bounded content type may inform scheduling, but a low-traffic type may need enough activity to exercise the paths that matter while a heavily edited type creates more opportunities to test workflow behavior. The observation period is complete when the predefined behaviors have actually been exercised.
Those behaviors should become cutover criteria before the parallel run begins. Require zero unresolved references, asset delivery that matches production performance, and one complete draft-review-publish cycle performed by the content team without support intervention. These checks test connected behavior rather than the presence of rows in a destination database. They also make the decision to proceed depend on observable operation rather than a clean import log.
Strict validation becomes useful during that proof because each failure points to a contained modelling problem. A rejected field, invalid reference, or missing relation exposes ambiguity inherited from the legacy model while only one bounded type is affected. Resolving the ambiguity there prevents it from becoming production debt in the new schema. A validation failure therefore forces a concrete data or modelling decision before the migration expands.
After the type survives demonstrated production traffic without a rollback, cutover can proceed. The source CMS can remain readable while becoming non-writable, preserving a reference point during later migration batches and retaining a viable source for rollback. The same handover supports an SEO-safe website migration because content behavior, asset paths, and public routing are tested before the old path is retired.
Each later run can then take on a more difficult bounded type using the same proof process. Teams still deciding whether the architectural change warrants this work can separately examine the “pros and cons of going headless” or the “risks of staying on a legacy CMS.” Teams already executing the migration may encounter “our headless CMS development work” and “our Contentful development services” as related service references; those commercial materials should remain separate from the technical criteria used to decide whether a bounded type is ready to move.
Automation executes an explicit model
After the destination model is decided, migration scripts and import APIs can handle repetitive work consistently. They can convert documents, rewrite asset URLs, create entries, establish references, split or merge localized content, and apply known transformations. Contentful, Strapi, and Storyblok import interfaces can accelerate these operations once the mappings they must implement are defined. Because all three companies sell CMS products and benefit when teams adopt their migration tooling and platforms, their interfaces should be evaluated against the mapped requirements of each bounded type.
That automation depends on decisions made before transfer begins. An import API cannot determine what a legacy shortcode was intended to mean, choose relationship cardinality, decide between locale-per-entry and locale-per-field, or infer the correct destination for a source field with no semantic equivalent. People establish the schemas, transformations, references, locales, supporting objects, and workflows; automation then applies those decisions repeatedly to the records that fit them.
Concluding thoughts
A headless CMS migration is not primarily a data-transfer project. It is a decision about which content structures, relationships, workflows, and publishing behaviors the business needs to preserve, replace, or redesign. That distinction matters when setting budgets and timelines: record counts may describe the volume being moved, but they do not describe the complexity of making that content work in a new system.
For executives, the useful unit of progress is a bounded content type that has been migrated and proven end to end. This creates measurable checkpoints for investment while containing failures before they affect the wider operation. It also gives technical and editorial teams a shared definition of completion based on working references, locales, assets, workflows, and production behavior rather than successful imports alone.
Platform selection should follow the same logic. Contentful, Strapi, Storyblok, and other headless systems make different assumptions about modelling, localization, publishing, and supporting objects. The right choice is the one whose constraints fit the organization’s content and operating model with an acceptable amount of transformation, not simply the one that can ingest the existing records fastest.
The migration is ready to expand when one bounded type works as intended under real conditions. Repeating that proof across increasingly complex types turns a potentially disruptive replatforming effort into a sequence of controlled business decisions, with clear evidence for when to proceed, when to correct the model, and when the legacy CMS can safely be retired.
A project in mind?
Schedule a 30-minute meeting with us.
Senior experts helping you move faster across product, engineering, cloud & AI.


