Migrate from Storyblok to Payload

Moving from Storyblok to self-hosted Payload means translating component schemas into code-defined collections and blocks, importing stories and assets, and rebuilding preview. This page sets out what moves cleanly, what needs rework and how to sequence the work.

On this page

How to migrate from Storyblok to Payload without losing editors' visual workflow

The move from Storyblok to Payload is a schema translation, a content import and a preview rebuild, not a file copy. Storyblok keeps components, stories and assets in its hosted space, so you cannot lift them across unchanged: each component becomes a Payload block or collection, each story becomes a document, and each editor-facing feature such as the visual editor's in-context preview has to be rebuilt in your own front end. Most teams that take this on are in-house platform or front-end engineers who already own the Next.js application, sometimes working with an implementation partner for the schema mapping and the preview work. Payload is MIT licensed and installs directly into a Next.js /app folder, so the CMS, its admin panel and the delivery code end up in a codebase your team controls, with the database on infrastructure you choose.

Expect the effort to sit mostly in the schema and preview work, not in the data transfer. Pull the components, stories, languages and assets with the Storyblok CLI first (the export steps are covered in the export guide), then map every nestable component group to a Payload block with its fields, validation and localization settings. Plan a short parallel run where editors compare pages built in Storyblok with the same pages in Payload, and confirm with your team how long the preview build will take, since live preview in Payload depends on your front-end routing and draft handling. Ask for a written scope that lists the components to migrate, the locales to recreate, the asset strategy and the preview acceptance criteria before anyone starts. The main risks are components with deeply nested content, rich text fields that carry Storyblok-specific markup, and editor roles that exist only in Storyblok and must be redefined in Payload's access control.

Confirm the current Payload release line and its database support before you commit, because the project publishes new versions frequently. Check the Payload GitHub repository and its releases page for the version your team will pin, and confirm whether PostgreSQL or MongoDB fits your hosting standards. Document the hosting choice early, since self-hosting means your team owns backups, upgrades and the database, costs that do not appear in a Storyblok invoice but still need an owner and a budget.

Which Storyblok capabilities map to Payload, and which need rework

This table maps each Storyblok concept to its closest Payload equivalent and marks it clean, needs rework or gap. Read the rework rows as work you will schedule in the migration plan, and treat the visual editor row as a gap you rebuild in code rather than a feature that carries over.

Storyblok conceptPayload equivalentStatus and what to plan
Stories (content with slugs and folders)Collections with draft and publish versions, plus URL fields or routing in your Next.js appNeeds rework: slugs, folder paths and published state must be rebuilt as fields and routes
Components and nestable blocksBlocks in a block-based layout builder field, or reusable field groupsNeeds rework: each Storyblok component schema is rewritten as TypeScript config
Component groups and presetsCode-organized block definitions and default values in configNeeds rework: groupings become file structure and default values, not a visual catalog
Datasources and option listsSelect fields with static options, or a separate collection referenced by relationshipNeeds rework: decide per datasource whether it becomes code or editable content
Languages and translationsBuilt-in localization with locales defined in configNeeds rework: locales are recreated and content is re-imported per locale; confirm the approach with your team
Assets with metadataUpload collection with file storage adapter and alt text fieldsNeeds rework: files and metadata are imported, storage location must be chosen
Rich text contentLexical rich text editor with its own JSON structureNeeds rework: Storyblok rich text must be converted into Lexical JSON and checked
Roles and permissionsField-level and collection-level access control in codeNeeds rework: Storyblok roles are not carried over and must be rewritten as access rules
Workflows and approvalsDrafts and versions, with hooks for custom review stepsGap: confirm whether a multi-step approval flow must be built as custom code
Visual editorLive preview in the admin panel, with your front end rendered for editorsGap: rebuilt in code. Developers must wire preview routes and editors will notice differences
API delivery (REST and GraphQL)Auto-generated REST and GraphQL APIs from collectionsNeeds rework: front-end queries and response shapes change, so update every consumer

What to export from Storyblok and what to rebuild by hand

Storyblok's CLI covers the content side of a migration: stories, components, datasources, languages and assets. The configuration around that content, such as roles, workflows, webhooks and tokens, does not move into Payload and has to be recreated by your team. Confirm every command and output format against Storyblok's current CLI documentation before you start, since the tooling changes.

Stories and their content

Stories hold the page and entry content that editors have written, including nested component data, slugs, and the publish state of each version. Pull them with the Storyblok CLI, then confirm the export includes draft and published content if your editors rely on both. In Payload, each story type usually becomes a collection, so map the JSON shape to collection fields before writing any import script. Check a sample of long stories for rich text and nested blocks, since those are where data loss tends to appear.

Component schemas and groups

Component schemas define the fields, field types, presets and groups that editors see in the visual editor. Export them with the CLI and treat the output as the specification for your Payload block and field config. Storyblok's nestable components have no one-to-one Payload equivalent, so decide early which ones become blocks, which become reusable groups, and which become plain fields. Keep a written mapping table for the team to review.

Datasources and option lists

Datasources hold the option lists that drive select fields, tags and taxonomy values across stories. Export them so that every value a selector depends on survives the move. In Payload, these usually become select fields, a related collection or a small taxonomy collection, depending on whether editors need to manage the values themselves. Verify that every option referenced by a story exists in the new config before you import content.

Languages and locale codes

Languages and their codes define the locales your stories are translated into. Export the language list first, then confirm the exact code format, since Payload's localization config must match it character for character. Translated fields in Storyblok are stored per language, so plan how each localized field will be populated in Payload and whether fallback locales are needed for untranslated content. Recreate the locale setup in the Payload config before any content import runs.

Assets and asset metadata

Assets include the files themselves plus alt text, titles, focal points and folder structure. The CLI can export asset metadata, but you must confirm whether the binary files download with it and how they are named. Plan for storage in your own object store, such as an S3-compatible service, and rewrite every asset URL in imported content. Spot-check that image focal points and alt text carried over, because editors notice these gaps quickly.

Roles, workflows and approval rules

Storyblok's roles, permissions, workflows and approval steps do not move into Payload. Access control in Payload is code-defined, so write field-level and collection-level access rules from your documented editorial matrix, not from memory. Workflow stages such as review and approval have to be rebuilt with Payload's versions and drafts, plus whatever approval process your team adopts. Ask a sample of editors to walk through their current tasks before you sign off on the new rules.

Webhooks, delivery tokens and integrations

Webhooks, API access tokens and third-party integrations sit outside the content export and must be inventoried by hand. List every site build hook, search indexer, translation connector and preview link that depends on Storyblok, then decide whether each is replaced, rewired or retired. Delivery tokens need new keys issued from Payload, and every consuming front end must be updated at cutover. Treat this list as a checklist for the cutover plan, not as an afterthought.

The migration sequence from inventory to decommission

This sequence moves a Storyblok space into a Payload project in controlled stages, so each schema, content set and locale is proven before editors depend on it. Each step produces a named artifact that the next step relies on, and the cutover happens only after a parallel run has passed review.

  1. Inventory components, stories and locales

    Before any code is written, the migration lead and the content owners list every component, component group, preset, datasource, language and asset folder in the Storyblok space, and record which stories are published, drafted or scheduled. Storyblok's own CLI can pull much of this inventory, and the export is covered in detail on the how to export your data from Storyblok page. The output is a component inventory with field types, nesting depth and usage counts, plus a list of roles and workflows that must be rebuilt by hand because they do not transfer. The step is done when the content owners have signed off the inventory.

  2. Translate component schemas into Payload config

    A developer runs a schema spike that maps each Storyblok component to a Payload collection, global or block, and records the decisions in a component map. Nestable components usually become blocks in a layout field, while shared content such as navigation or footer data may fit better as a global. Payload generates TypeScript types from the code-defined fields, so the spike also checks that the generated types match what the front end expects. The output is a versioned component map and a Payload project that starts, builds and renders empty collections without errors.

  3. Run a pilot collection with a few stories

    The team picks a small set of stories that together use the most common components, nested blocks, rich text, images and at least two locales. They import these stories through a script that reads the Storyblok content API and writes to the matching Payload collections. The pilot shows where the component map is wrong, where field types need adjusting and how long a full import will take to run on your own database. The step is complete when the pilot stories render on the front end and an editor can open and change them in the Payload admin panel.

  4. Import rich text and assets with validation

    Storyblok rich text is converted into Payload's Lexical rich text format, and embedded assets are downloaded from Storyblok and uploaded to your own storage with their alt text and metadata. Each import run writes a report that counts stories, blocks, rich text nodes and assets processed, and lists every record that failed or was transformed in a way that needs review. Links to assets must be rewritten to point at the new storage location. The step ends with a validated import report that the content team has checked against a sample of the source stories.

  5. Recreate locales and access rules

    The team configures Payload's localization settings to match the languages in the Storyblok space, including default and fallback locales, and runs the import once per locale so translated fields land in the right place. Editor and reviewer roles are then rebuilt with Payload's field-level access control and authentication, since Storyblok roles and permissions do not carry over. The output is a locale matrix showing each collection and field that is translatable, together with a role matrix signed off by the security owner.

  6. Set up live preview for editors

    Editors use Storyblok's visual editor to see changes in context, so the developers rebuild that workflow with Payload's live preview feature and a front end that renders draft content through a preview route. They must confirm that preview respects drafts and versions, that each block can be previewed in its page context, and that the preview endpoint is protected from public access. The step is done when a small group of editors has completed a trial session and listed the places where the preview differs from the Storyblok experience.

  7. Run both systems in parallel

    For a defined period, editors keep working in Storyblok while the team re-runs the import on a schedule and compares published output from both systems on the same pages. Differences in content, locale fallback, asset URLs and preview behavior are logged, fixed in the import script or the front end, and retested. Running in parallel exposes gaps that a single pilot cannot, such as stories edited late in the day or scheduled releases. The output is a discrepancy log that is empty for agreed critical pages.

  8. Cut over and decommission Storyblok

    The team freezes edits in Storyblok, runs a final import, points the production front end and API consumers at Payload, and confirms that editors can publish on the new system. Before the Storyblok subscription is ended, the team exports a final snapshot and stores it under the organization's retention policy, since access to the source space will stop. The step is complete when the content owner signs off the cutover, the final export is verified, and the Storyblok space and API tokens are removed from all integrations.

How component schemas become Payload config in TypeScript

The first decision is which Storyblok components become Payload blocks and which become collections. A nestable component that only exists inside a page, such as a hero, a feature grid or a call-to-action, usually maps to a block in a layout field, because editors add it to a story and never look it up on its own. A component that is referenced from many stories and needs its own list, such as an author, a product or a press release, usually becomes a collection with relationship fields pointing at it. Storyblok does not force this split, so inventory each component's usage across stories before you write any config. Components that appear in both roles are the ones to settle in a pilot, because they are the easiest to model wrongly.

Each Storyblok schema field then becomes a Payload field in a TypeScript config file, such as payload.config.ts and the collection files it imports. Text, number, boolean, select, asset and link fields have direct equivalents, but field types, validation rules and conditional display logic may not map one to one, so confirm coverage for every field type your schemas use. Because Payload generates TypeScript types from these code-defined collections and fields, the generated types become the contract your front end compiles against. Run the schema translation against a sample of real stories and check that the generated types match what the front end reads. Treat that check as part of the migration, not a clean-up task after launch.

Rich text is the most likely place for content to change shape. Storyblok stores rich text as a structured JSON tree, and Payload uses the Lexical rich text editor, so the conversion has to map Storyblok node and mark types onto Lexical nodes, including embedded blocks inside rich text. Asset metadata is simpler but still needs a plan: alt text, titles, focal points, copyright notes and file references should be carried into Payload upload collections, with the original file location recorded so you can verify each asset arrived. Ask your implementation partner to show a sample rich text story and a sample image with its metadata rendered side by side before you commit to the mapping.

How the move differs by content estate and team

A small marketing site usually has a handful of content types, a short list of Storyblok components such as heroes, feature grids and CTAs, and one or two languages. In this situation the migration is mostly a translation exercise. The schema is small enough that one developer can read every component and write the matching Payload collection or block in a single pass, and the rendering code in the Next.js app is often the larger share of the work.

  • Scope: Export every story and component with the Storyblok CLI, then confirm the counts match before writing any code.
  • Sequencing: Build the Payload blocks first, then import a small set of pages to test rendering before moving the rest.
  • Ownership: One developer can own the schema translation, with a marketing lead reviewing the field names and labels editors will see.
  • Preview: Set up live preview on one page type first, since a small site gives editors a quick way to test the result.
  • Redirects: Plan URL mapping early, because a small site still needs its published URLs preserved.

Before you start, confirm with your team how many components are actually in use, since unused components in the Storyblok space are often not worth recreating.

What drives the cost and duration of a Storyblok to Payload move

This table lists the factors that change the effort of moving Storyblok content into Payload collections and blocks, with how each one affects the work and how to keep it contained. Read it before requesting a quote, because the scope items named here are what a written estimate should itemize. The main takeaway is that component count, locales and custom integrations usually matter more than raw content volume.

DriverWhy it mattersHow to keep it down
Component count and nesting depthEach Storyblok component becomes a Payload block or group with its own field definitions, and deeply nested bloks multiply the mapping and testing work.Audit the component library first, merge near-duplicate components and flatten nesting where editors do not need it.
Number of localesEach locale needs recreated localized fields, translated content mapping and checks that fallbacks behave the same way as in Storyblok.Confirm which locales are live and which are retired before export, and migrate only active locales in the first pass.
Rich text and asset volumeStoryblok rich text must be converted to Payload's Lexical structure, and asset files and metadata must be downloaded and re-linked.Agree a conversion sample early, decide which assets are still referenced, and script the transfer rather than moving files by hand.
Custom integrations and datasourcesWebhooks, datasource lookups and third-party services attached to Storyblok must be rebuilt as Payload hooks, endpoints or front-end code.Inventory every integration and mark which ones are still needed, since retiring unused ones removes work.
Approval workflows to rebuildStoryblok workflow steps and roles do not carry over in the CLI pull, so approval paths must be designed and configured in Payload access control and hooks.Document the current approval states and who signs off on each, then reduce them to the fewest states editors actually use.
Live preview complexityVisual preview requires a front-end route that renders draft content in the Next.js app, and the effort grows with the number of page templates.Limit preview to the highest-traffic templates in the first release and confirm editor expectations before building generic preview.
Hosting and database choicePayload runs on MongoDB, PostgreSQL or SQLite, and the chosen database and deployment target set the setup, backup and scaling work.Pick the database your team already operates and confirm the deployment target in writing before implementation starts.
One-time versus recurring workSchema mapping, content migration, preview build and testing are one-time, while hosting, database operations, upgrades and support recur after go-live.Ask the quote to separate one-time delivery from ongoing run costs, and state which upgrades and support tiers are included.

What usually goes wrong and how to prevent it

Most failed Storyblok to Payload migrations do not fail on the import itself. They fail afterward, when editors find that preview, locales, links or integrations behave differently. Each card below names one failure point, why it matters for this move, and the check that catches it before cutover.

Losing the editor workflow in preview

Storyblok's visual editor lets editors click into a page and edit in context. Payload offers live preview, but a developer has to wire the preview route, pass draft data and render each block so the preview matches the published page. Build preview for every block type before editors are invited, and ask a sample of editors to edit a live page from start to finish in staging. Note any step where they reach for the old tool.

Locale fallbacks breaking after import

Storyblok stores translations per language and falls back to a default when a field is empty. Payload localization has its own fallback settings, and if they differ, untranslated entries can render blank or in the wrong language. Confirm the fallback behavior in the Payload localization configuration, then import one story in three languages and check each field, including empty ones, against the source space.

Lossy rich text conversion

Storyblok rich text is a JSON tree, and Payload uses the Lexical editor with its own node model. Custom Storyblok blocks embedded in rich text, marks, and link attributes may not map one to one. Run a conversion test on the 20 most complex stories and diff the rendered HTML before and after, paying attention to embedded components, anchors and footnotes.

Asset URLs breaking at cutover

Stories often embed direct links to Storyblok asset hosts, and those links stop working once the space is closed or the subscription lapses. Move files to storage you control, rewrite every reference in the imported content to the new host, and keep redirects for any public URL that editors or search engines already use. Scan the rendered site for remaining references to the old asset domain before DNS changes.

Undocumented Storyblok integrations

Webhooks that trigger builds, datasource lookups, translation connectors and scheduled publishing often live in the Storyblok admin rather than in code. Nothing in the export tells you they exist. Inventory every webhook, app and external consumer of the Storyblok API by asking the content team and the engineering team, then assign an owner and a replacement for each one before the old space is turned off.

Editors trained on the wrong workflow

Training built around the Storyblok interface teaches editors to look for features that Payload places differently, such as drafts, versions and publish schedules. Editors trained on screenshots of the old tool often make errors in the new one. Write a short runbook for the tasks your editors perform most often, run a supervised session on the staging site, and schedule a support window for the first two publishing cycles after cutover.

Questions teams ask before moving from Storyblok to Payload

How much effort and cost does moving from Storyblok to Payload involve?

The effort depends mostly on how many components, content types and locales you have, and how much rich text and asset metadata must carry over. Payload itself is MIT licensed, so the software line item is zero, but you pay for the people who translate your component schemas into code, the hosting for Payload and its database, and ongoing maintenance. Payload is also a Next.js native CMS, so your front end work counts toward the total if you are rebuilding it. Ask any partner for a quote that splits schema translation, content import, asset transfer, preview setup, and hosting into separate lines, so you can see what is one-time and what recurs.

How long does the migration take, and what makes it vary?

Duration varies with the size of your component library, the number of stories and locales, and whether your front end already runs on Next.js. Teams with few components and clean content usually finish faster than teams with deep nesting, custom datasources and many languages. Live preview and editor training also add time, because editors need to confirm that the visual workflow works before you switch. No supplied timeline applies to your space, so ask for a written schedule tied to a defined scope before work starts.

What does the work need from our team?

Plan for time from three groups: engineers who know your current front end and can review the new Payload collections and blocks, content owners who can confirm which stories, languages and assets must move, and an editor or two who can test the preview and publishing flow. You also need someone who controls the hosting account, database, and DNS, and who can approve the cutover. Decisions about roles, workflows and approval steps will need to be made again in Payload, because those settings do not come across automatically.

Can our own developers do the migration without an outside partner?

Yes, if your developers already know TypeScript, Next.js and a database such as PostgreSQL or MongoDB. Payload generates TypeScript types from its code-defined collections and fields, which helps when you map Storyblok components by hand. The harder parts are usually live preview, rich text conversion and verification, because they touch the editor experience and content integrity. If your team has no time for that work, a fixed-scope engagement with DeployOpen can cover the implementation, with the scope and deliverables agreed in writing before work starts.

Does Payload keep the visual editing experience editors have in Storyblok?

Payload offers live preview and a block-based layout builder, but it does not reproduce Storyblok's visual editor out of the box. Developers must build the preview connection between the admin panel and the front end, and the result depends on how your Next.js pages render blocks. Editors should expect a different workflow, so run a test with real content before committing. Confirm the exact preview behavior with the Payload documentation and your own prototype rather than relying on a general promise.

How do we verify that the import is complete and correct?

Compare counts and content on both sides before cutover. Export your Storyblok space first using the Storyblok CLI, then check that every story, component, datasource, language and asset is present in Payload, and sample rich text pages to confirm formatting survived. Reconcile asset files against their URLs and metadata, and confirm that each locale renders the right fallbacks. Record the checks in a written checklist so the sign-off is traceable, and keep the Storyblok export as an archive until your editors have signed off on the new system.

Which Payload version should we plan around?

Payload v3.91.0 was released on October 15, 2026, and a v4.0.0 beta line is in progress, with v4.0.0-beta.2 published on October 16, 2026. Because a major version is in beta, plan on the stable v3 line for production work unless you have confirmed that v4 is ready for your use. Check the release notes before you pin a version, and ask your implementation partner how upgrades will be tested and scheduled after go-live.

How DeployOpen scopes, runs and supports the Payload migration

DeployOpen plans, implements, customizes, integrates, hardens, backs up, documents and supports self-hosted open-source platforms inside your own infrastructure. For a move from Storyblok to Payload, we start from a written scope that names the spaces, components, locales and assets involved, then build and test the Payload project in your environment.

How we scope

  • Inventory Storyblok components, stories, datasources, languages and assets before any estimate is written
  • Agree in writing which content types, locales and editor workflows move into Payload collections and blocks
  • Confirm where Payload will run, including the database choice between MongoDB, PostgreSQL and SQLite
  • Engagements are fixed-scope, with deliverables and timelines agreed before work starts

How we build

  • Translate Storyblok component schemas into code-defined Payload collections, blocks and TypeScript types
  • Script repeatable imports of stories, rich text and assets, then test them against a staging copy
  • Recreate locales and access rules, and configure live preview so editors keep an in-context workflow
  • Test the migrated content, preview behavior and field-level access before any cutover is scheduled

How we hand over

  • Document the schema, import scripts, environment setup and the reconciliation checks used to confirm completeness
  • Record which Storyblok roles, workflows and webhooks were rebuilt by hand, so nothing is assumed to carry over
  • Walk your engineers and content editors through the admin panel and preview setup in your own environment
  • Provide backup and restore procedures for the Payload database and uploaded asset storage

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer after handover
  • Plan Payload version upgrades against the release notes, including any move between major versions
  • Keep a retainer scope for content model changes that editors request after launch
  • Ask for the support scope, response expectations and upgrade cadence to be written into the agreement

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.