Optimizely to Storyblok Migration CLI

Surjit

Surjit Bharath

Founder of Hidden Foundry

Storyblok Architect ~ Optimizely Most Valued Professional (OMVP) ~ CMS and Commerce certified

Contact Me

Optimizely to Storyblok Migration CLI

When moving a customer from one CMS to another, developers often find themselves repeating the same tedious setup work—cataloging content types, recreating fields, aligning validators, and wiring up relationships. These manual steps are time-consuming, error-prone, and inconsistent across environments.

To reduce the amount of repetitive developer effort required, I’ve created a cross-platform CLI that helps teams migrate from Optimizely to Storyblok. We’re rolling this out in phases: Phase 1 focuses on migrating content types (component schemas), while future phases will extend to content (entries) migration and beyond.



What it does today (Phase 1)

  • Pulls content type definitions from Optimizely (Content Definitions API).

  • Saves them as a standardized JSON snapshot

  • Pushes those schemas into Storyblok as components/fields.

  • Safe to re‑run: only creates/updates what’s different.


Install (dotnet tool)

Requires .NET 9 (dotnet --info).

Pre‑release

dotnet tool install -g cms2storyblok --prerelease


If the command isn’t found: add the global tools path to your PATH.

  • macOS/Linux: ~/.dotnet/tools

  • Windows: %USERPROFILE%\.dotnet\tools



1) Discover Optimizely schemas → JSON


macOS/Linux (zsh/bash)

export OPTI_BASE_URL="https://<your-opti-host>/api"
cms2storyblok optimizely-schema \--base-url "$OPTI_BASE_URL"


Windows (PowerShell)

$env:OPTI_BASE_URL = "https://<your-opti-host>/api"
cms2storyblok optimizely-schema `
--base-url $env:OPTI_BASE_URL `

This creates files like ./schemas/OptimizelySchema_20250911_114501.json.


2) Push schemas → Storyblok components


macOS/Linux (zsh/bash)

export STORYBLOK_MANAGEMENT_TOKEN="<your-storyblok-token>"
export STORYBLOK_SPACE_ID="<your-space-id>"

cms2storyblok schema:push \
--input ./schemas/OptimizelySchema_20250911_114501.json \
--space "$STORYBLOK_SPACE_ID" \
--token "$STORYBLOK_MANAGEMENT_TOKEN"

 

Windows (PowerShell)

$env:STORYBLOK_MANAGEMENT_TOKEN = "<your-storyblok-token>"
$env:STORYBLOK_SPACE_ID = "<your-space-id>"

cms2storyblok schema:push `
--input .\schemas\OptimizelySchema_20250911_114501.json `
--space $env:STORYBLOK_SPACE_ID `
--token $env:STORYBLOK_MANAGEMENT_TOKEN


Tip: add --dry-run to preview changes without writing.


What’s next (Phase 2+)

  • Content migration: export entries from Optimizely and import as Storyblok stories.

  • Assets: fetch/upload referenced media.

  • Validators & constraints: map required/regex/min/max where possible.

  • Transforms: field‑level shaping (e.g., rich‑text conversions, reference normalization).

If you want to try the CLI or have edge cases, I’d love feedback. Phase 2 (content migration) is up next.

;