Content Modeling for Migrations: Field Patterns We Use on Every Project
BY DEV KAPOOR · Jul 21, 2026 · 7 MIN READ

A legacy CMS migration is not a plugin inventory exercise. Plugins are implementation details. Content is the asset. Every migration we run starts the same way: a content inventory where each legacy content type gets one row — what it is, who edits it, how it relates to other content, and what it becomes in Payload.
Map content, not plugins
WordPress post types, ACF field groups, and taxonomy soup almost always reduce to a small set of clean collections. A typical 40-type WordPress install maps to 8–12 Payload collections once you stop modeling around plugin boundaries and start modeling around the business.
Groups replace ACF field relationships
ACF field groups map almost one-to-one to Payload groups — with the difference that the structure lives in typed code instead of a database table managed by a plugin UI:
fields: [
{
name: 'seo',
type: 'group',
fields: [
{ name: 'title', type: 'text' },
{ name: 'description', type: 'textarea' },
],
},
]Blocks replace shortcodes
Every WordPress shortcode embedding an arbitrary blob of behavior becomes a typed block. Editors get constrained, structured options instead of a text field that silently holds ten years of regex surgery:
const Feature: Block = {
slug: 'feature',
fields: [
{ name: 'heading', type: 'text', required: true },
{ name: 'body', type: 'textarea' },
],
}Drafts and versions, for free
The feature clients ask for most — "can we schedule and review changes?" — is drafts and versions, enabled per collection in Payload with one flag. No plugin, no migration of revision tables.
The pattern holds across every project we've run: model the content, delete the plugin, and the system gets simpler every week after launch.
Want this kind of thinking applied to your stack?
We migrate teams from WordPress, Drupal, and other legacy CMS platforms to Payload — and we publish our playbook as we go.
START A CONVERSATION