migrate
Run content and preset migration pipelines.
migrate
sb-mig migrate content --all --from <space> --to <space> --migration <name>
sb-mig migrate presets --all --from <space-or-file> --to <space> --migration <name>
sb-mig migrate continuemigrate loads local migration config files, applies them in memory, writes
artifacts, and then writes changed stories or presets unless --dry-run is
passed. migrate continue finishes a previous --dry-run by replaying its
saved result to Storyblok without re-running the preparation phase.
Shared flags
Exact flag names on this page include fromFilePath, migrationComponentAlias, migrationComponents, withSlug, startsWith, publicationMode, publicationLanguages, languagePublishStatePath, and fileName.
| Flag | Type | Applies to | Effect |
|---|---|---|---|
--from | string | content, presets | Source space ID. With --migrate-from file, it can be a local backup file name. |
--fromFilePath | string | content, presets | Direct path to a stories or presets JSON file when --migrate-from file is used. |
--to | string | content, presets | Target Storyblok space ID. |
--migrate-from | space or file | content, presets | Read source items from Storyblok or local JSON. Default: space. |
--migration | repeatable string | content, presets | Migration config name without extension. Content supports multiple ordered values. Presets support one value. |
--migrationComponentAlias | repeatable string | content, presets | Add mapper aliases. Format: <migration>:<source>=<alias1>,<alias2>. |
--migrationComponents | repeatable string | content, presets | Override exact component scope. Format: <migration>:<component1>,<component2>. |
--dry-run | boolean | content, presets | Apply migration in memory and write artifacts without Storyblok writes. |
--fileName | string | content, presets | Stable artifact base name. Also disables datestamped artifact names. |
--yes | boolean | content, presets | Skip confirmation prompt for real writes. |
content
Primary form
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-name \
--dry-run--all means "select all non-folder stories, then run the component mappers
defined by the migration config." It does not mean every component must change.
Only stories whose JSON changes are written to the *-to-migrate artifact and,
in real runs, to Storyblok.
Content-only flags
| Flag | Type | Effect |
|---|---|---|
--all | boolean | Select all non-folder stories in scope. |
--withSlug | repeatable string | Select exact story full_slug values. |
--startsWith | string | Select stories whose full_slug starts with the prefix. |
--publicationMode | enum | preserve-layers, collapse-draft, or save-only. Default: preserve-layers. |
--publicationLanguages | string | default, all, or comma-separated language codes. Default for publishing modes: all. |
--languagePublishStatePath | string | Reuse a JSON map generated by language-publish-state. |
Story selection
Select all non-folder stories:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-nameSelect exact slugs:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-name \
--withSlug blog/home \
--withSlug docs/getting-startedSelect a subtree by prefix:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-name \
--startsWith blog/Scoped component migrations
Use --migrationComponents to restrict one migration to specific component
names:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration colorPickerModeValues \
--migrationComponents colorPickerModeValues:sb-section,sb-tour-page-sectionUse --migrationComponentAlias when another component should reuse an existing
mapper:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration colorPickerModeValues \
--migrationComponentAlias colorPickerModeValues:sb-button=sb-open-drift-buttonYou can combine aliases and overrides. Alias first, then include the alias in the override list if you want the migration scoped to only those components:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration colorPickerModeValues \
--migrationComponentAlias colorPickerModeValues:sb-button=sb-open-drift-button \
--migrationComponents colorPickerModeValues:sb-button,sb-open-drift-buttonThe help output currently lists sb-mig migrate content <component-name ...>.
In 6.1.1-beta.1, the built CLI rejects that combination because the default
migrateFrom flag is present during command matching. Use --all plus
--migrationComponents for deterministic scoped migrations.
Multiple migration steps
Content migrations can run multiple configs in order:
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-a \
--migration migration-b \
--migration migration-c \
--yesEach step gets its own pipeline summary entry. If a migration has a matching validator, the validator runs after that step.
File input
Read from a discovered local backup file name:
sb-mig migrate content --all \
--migrate-from file \
--from file-with-stories \
--to 12345 \
--migration migration-nameRead from an explicit file path:
sb-mig migrate content --all \
--migrate-from file \
--fromFilePath sbmig/migrations/dry-run--12345---story-to-migrate.json \
--to 12345 \
--migration migration-a \
--migration migration-bWhen --fromFilePath is used and --from is omitted, sb-mig derives the
artifact base name from the file path.
Publication modes
| Mode | Behavior | Constraints |
|---|---|---|
preserve-layers | Default. Migrates draft/current and latest published layer for dirty published stories, publishes the migrated published layer, then restores migrated draft/current. | Requires --migrate-from space and --from equal to --to. |
collapse-draft | Migrates draft/current only. Published stories can be republished from the migrated draft/current layer. Dirty draft content becomes the published content. | Works for duplicated-space workflows where preserving a separate published layer is not required. |
save-only | Saves migrated draft/current content and never publishes. | Cannot be combined with --publicationLanguages or --languagePublishStatePath. |
Legacy flags are rejected:
| Old flag | Replacement |
|---|---|
--publish | --publicationMode preserve-layers or --publicationMode collapse-draft |
--publishLanguages | --publicationLanguages |
--preservePublishedLayer | --publicationMode preserve-layers |
Publication languages
--publicationLanguages default
--publicationLanguages all
--publicationLanguages default,fr,dedefault maps to Storyblok's default-language publish token. all resolves the
target space languages and publishes [default] plus configured language codes.
When a publishing mode is active and --languagePublishStatePath is omitted,
sb-mig builds a language publish-state map automatically for the selected
stories. For sensitive runs, generate the map first:
sb-mig language-publish-state \
--from 12345 \
--startsWith blog/ \
--languages all \
--fileName blog-prod
sb-mig migrate content --all \
--from 12345 \
--to 12345 \
--migration migration-name \
--publicationMode preserve-layers \
--publicationLanguages all \
--languagePublishStatePath sbmig/language-publish-state/blog-prod.json \
--yespresets
Valid forms
sb-mig migrate presets --all \
--from 12345 \
--to 12345 \
--migration preset-migration \
--dry-run
sb-mig migrate presets --all \
--migrate-from file \
--fromFilePath sbmig/presets/presets-backup.json \
--to 12345 \
--migration preset-migrationPreset constraints
| Constraint | Reason |
|---|---|
Exactly one --migration value | Preset migration pipelines do not support multiple ordered configs yet. |
--publicationMode is rejected | Presets cannot be published. |
--publicationLanguages is rejected | Presets cannot be published by language. |
--languagePublishStatePath is rejected | Presets do not use story publish-state maps. |
Before a real preset run, sb-mig backs up all remote presets to
presets-backup.
continue
continue finishes a previous migrate content --dry-run by writing its
already-computed result to Storyblok. It skips the expensive preparation a dry
run already did — pulling stories, applying mappers in memory, and fetching
published layers and language state — and replays only the writes. On large
spaces this turns the "dry run, then real run" workflow from roughly double the
cost into one preparation plus a fast write, so always running a dry run first
no longer doubles the wait.
continue assumes a content freeze between the dry run and the continue run.
The source space must not change in between: continue trusts the dry run's
result and does not re-read or diff the space (no drift detection).
Primary form
sb-mig migrate continuecontinue discovers the dry run's continue manifest in sbmig/migrations,
prints a summary of what it will write (space, publication mode, languages,
story counts, and the artifacts it will use), and prompts for confirmation
before writing.
continue-only flags
| Flag | Type | Effect |
|---|---|---|
--manifest | string | Continue manifest filename inside sbmig/migrations. Only needed when more than one dry-run manifest is present. |
--yes | boolean | Skip the confirmation prompt for the write. |
Manifest discovery
| Situation | Behavior |
|---|---|
Exactly one continue manifest in sbmig/migrations | Used automatically. |
| More than one | Stops and lists them; pass --manifest <filename> to pick one. |
| None | Errors and points you at migrate content … --dry-run. |
Equivalent to a real run
continue writes exactly what a real migrate content would: it updates
applied-backpack-migrations.json, performs the same Storyblok writes
(including the preserve-layers dual-layer write for dirty published stories),
and writes a migration run log tagged with the originating manifest.
It performs no bulk story fetch, no in-memory migration, no published-layer fetch, and no language-state fetch. The only read it still makes is the existing per-story safety re-fetch inside the preserve-layers dual-layer write.
Artifacts and side effects
For --migrate-from space real runs, sb-mig writes a pre-migration backup under
sbmig/backup/story or sbmig/backup/preset.
All content and preset runs write migration artifacts under sbmig/migrations.
Dry runs return before Storyblok writes. Real runs also write a JSONL migration
run log after Storyblok write attempts complete.
A content dry run additionally writes a *-continue-manifest file (and, for
preserve-layers, a *-dirty-published-records file) that migrate continue
uses to replay the run. The dry run's *-input-full artifacts are the
pre-migration snapshot for that workflow, since continue does not re-read the
space to take its own backup.
sb-mig