A step-by-step guide for developers migrating from Storyblok to Cosmic: content model mapping, component-to-metafield conversion, media migration, API migration, and webhooks — with real TypeScript code examples.
Why Developers Are Migrating from Storyblok to Cosmic
Storyblok was a smart choice for teams who wanted a visual editor baked into their CMS. But as applications grow in complexity and AI becomes central to content operations, its limitations become harder to work around. Three pain points keep coming up in migration conversations:
Visual editor lock-in. Storyblok components are built around page presentation, which couples your content model to your frontend. When you need to reuse content across channels, that coupling becomes a bottleneck.
Pricing pressure. Seat fees, delivery limits, and add-on costs compound as teams grow. Budgeting for Storyblok at scale is unpredictable.
No native AI. Adding AI to a Storyblok workflow requires third-party integrations and significant custom engineering. Cosmic has AI Agents built in.
If any of those sound familiar, this guide will walk you through the full migration process: content model mapping, component-to-metafield conversion, media migration, API migration, and webhooks.
Before You Start: Understanding the Key Differences
| Storyblok Concept | Cosmic Equivalent |
|---|---|
| Story | Object |
| Component/Block | Object Type + Metafields |
| Component Field | Metafield |
| Space | Bucket |
| Asset | Media |
| Datasource | Object Type (for structured reference data) |
| Webhook | Webhook (via add-on) |
The most important conceptual shift: Storyblok organizes content around components on stories. Cosmic organizes content around Objects of a given Object Type. The result is more flexible — you're not constrained by what a visual editor can preview.
Step 1: Map Your Content Model
Start by auditing your Storyblok components. For each component, you'll create a corresponding Object Type in Cosmic with the right Metafields.
Field type mapping reference:
- Storyblok
richtext→ Cosmichtml-textareaormarkdown - Storyblok
asset→ Cosmicfile - Storyblok
text→ Cosmictext - Storyblok
textarea→ Cosmictextarea - Storyblok single select → Cosmic
select - Storyblok multi select → Cosmic
multi-select - Storyblok nested blocks → Cosmic relationship field or
objects - Storyblok reference → Cosmic relationship field (
object)
Step 2: Export Your Content from Storyblok
Use the Storyblok Management API to export your stories. You'll need your Storyblok API token.
const response = await fetch(
`https://mapi.storyblok.com/v1/spaces/${SPACE_ID}/stories`,
{
headers: {
Authorization: STORYBLOK_MANAGEMENT_TOKEN,
},
}
);
const { stories } = await response.json();
Step 3: Migrate Media Assets
Before importing content objects, migrate your media. Storyblok stores assets on their CDN; you'll need to re-upload them to Cosmic's media library.
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
bucketSlug: process.env.COSMIC_BUCKET_SLUG,
readKey: process.env.COSMIC_READ_KEY,
writeKey: process.env.COSMIC_WRITE_KEY,
});
async function migrateAsset(storyblokUrl: string, filename: string) {
const response = await fetch(storyblokUrl);
const buffer = await response.arrayBuffer();
const file = new File([buffer], filename);
const { media } = await cosmic.media.insertOne({ media: file });
return media.imgix_url;
}
Step 4: Import Content to Cosmic
With your content model mapped and media migrated, import your stories as Cosmic Objects using the JavaScript/TypeScript SDK.
async function importStory(story: StoryblokStory, mediaMap: Record<string, string>) {
await cosmic.objects.insertOne({
title: story.name,
type: 'your-object-type-slug',
status: story.published ? 'published' : 'draft',
metadata: {
content: story.content.body,
image: mediaMap[story.content.image?.filename] || '',
// map other fields as needed
},
});
}
Step 5: Update Your API Calls
Storyblok and Cosmic have different API patterns. Here's how to update your frontend code.
Before (Storyblok):
import { storyblokInit, apiPlugin } from '@storyblok/react';
storyblokInit({
accessToken: process.env.STORYBLOK_TOKEN,
use: [apiPlugin],
});
const { data } = await storyblokApi.get('cdn/stories', {
version: 'published',
});
After (Cosmic):
import { createBucketClient } from '@cosmicjs/sdk';
const cosmic = createBucketClient({
bucketSlug: process.env.COSMIC_BUCKET_SLUG,
readKey: process.env.COSMIC_READ_KEY,
});
const { objects } = await cosmic.objects.find({
type: 'your-object-type-slug',
}).props('id,title,slug,metadata');
Important: Cosmic uses the REST API only. There is no GraphQL endpoint.
Step 6: Migrate Webhooks
If you use Storyblok webhooks to trigger builds or revalidation, you'll need to set up Cosmic webhooks. Cosmic webhooks are available as an add-on ($99/month, or included in the $199/month bundle). Once enabled, configure them in the Cosmic dashboard under Settings > Webhooks.
Migration Checklist
Content Model
- [ ] Audit all Storyblok components and fields
- [ ] Create corresponding Object Types in Cosmic dashboard
- [ ] Map all field types (richtext → markdown, asset → file, etc.)
- [ ] Test Object Type schemas with sample content
Media
- [ ] Export list of all Storyblok assets
- [ ] Run media migration script
- [ ] Verify asset URLs in Cosmic media library
- [ ] Build asset URL map for content import
Content
- [ ] Export all Storyblok stories via Management API
- [ ] Run content import script
- [ ] Verify published/draft status is correct
- [ ] Spot-check content in Cosmic dashboard
API Integration
- [ ] Replace Storyblok SDK imports with Cosmic SDK
- [ ] Update all API calls to use Cosmic REST API
- [ ] Update environment variables
- [ ] Test all content queries in development
Webhooks and Automation
- [ ] Recreate Storyblok webhooks in Cosmic
- [ ] Update webhook endpoints in your applications
- [ ] Test build triggers and cache revalidation
Go Live
- [ ] Run full content audit comparing Storyblok and Cosmic
- [ ] Update DNS / CDN configuration if needed
- [ ] Monitor error rates after launch
- [ ] Deprecate Storyblok account once migration is confirmed
Supported Frameworks
Cosmic works with all major JavaScript frameworks:
- Next.js — Full support including App Router and Pages Router
- React — Works with any React setup
- Vue — Full compatibility
- Nuxt — Server-side rendering and static generation
- Astro — Content collections and SSR
- Remix — Loader-based data fetching
- Svelte / SvelteKit — Full support
- Gatsby — Static generation
The Cosmic JavaScript/TypeScript SDK works in any Node.js environment and in modern browsers.
This article was originally published on the Cosmic blog.
Top comments (0)