@storyblok/migrations (Version 1.x)
@storyblok/migrations provides migration utilities for Storyblok. It exports functions for reading and writing local Storyblok resources, converting URLs to Storyblok field objects, transforming HTML and Markdown into Storyblok rich text, and performing bulk content operations like reference remapping and schema-based cleanup.
Requirements
Section titled “Requirements”- Node.js LTS (version 22.x recommended)
Installation
Section titled “Installation”Add the package to a project:
npm install @storyblok/migrations@latesturlToLink()
Section titled “urlToLink()”urlToLink(url);urlToLink(url, options);Converts a plain URL string into a StoryblokMultilink object. The function detects mailto: links and produces linktype: 'email' accordingly. It also extracts #fragment anchors automatically.
import { urlToLink } from "@storyblok/migrations";
const cta = urlToLink("https://example.com/pricing#plans", { target: "_blank", title: "See plans",});urlToLink() accepts the following parameters:
url | A URL string. Supports https://, http://, and mailto: schemes. |
|---|---|
options | An optional object with additional link properties. |
The options object accepts the following properties:
target | The link target: '_blank' or '_self'. |
|---|---|
title | A title attribute for the link. |
rel | A rel attribute value (e.g., 'noopener'). |
anchor | An anchor fragment to append to the URL. |
urlToAsset()
Section titled “urlToAsset()”urlToAsset(url);urlToAsset(url, options);Converts a plain URL string into a StoryblokAsset object with is_external_url: true. The function derives the name from the last path segment of the URL.
import { urlToAsset } from "@storyblok/migrations";
const heroImage = urlToAsset("https://cdn.example.com/hero.jpg", { alt: "Hero image",});urlToAsset() accepts the following parameters:
url | A URL string pointing to the asset. |
|---|---|
options | An optional object with additional asset properties. |
The options object accepts the following properties:
alt | Alternative text for the asset. |
|---|---|
title | A title for the asset. |
copyright | Copyright information. |
focus | A focal point string. |
htmlToStoryblokRichtext()
Section titled “htmlToStoryblokRichtext()”htmlToStoryblokRichtext(html);htmlToStoryblokRichtext(html, options);Parses an HTML string and converts it into a Storyblok rich text document node. This function is re-exported from @storyblok/richtext.
import { htmlToStoryblokRichtext } from "@storyblok/migrations";
const doc = htmlToStoryblokRichtext("<p>Hello <strong>world</strong></p>");htmlToStoryblokRichtext() accepts the following parameters:
html | An HTML string to parse. |
|---|---|
options | An optional object with parser configuration. |
The options object accepts the following properties:
allowCustomAttributes | When true, the parser preserves custom HTML attributes. |
|---|---|
normalizeWhitespace | When true, the parser normalizes whitespace in text nodes. |
resolvers | A record of custom element resolvers keyed by tag name. |
styleOptions | An array of style options for inline style handling. |
markdownToStoryblokRichtext()
Section titled “markdownToStoryblokRichtext()”markdownToStoryblokRichtext(markdown);markdownToStoryblokRichtext(markdown, options);Parses a Markdown string and converts it into a Storyblok rich text document node. This function is re-exported from @storyblok/richtext.
import { markdownToStoryblokRichtext } from "@storyblok/migrations";
const doc = markdownToStoryblokRichtext("# Hello\n\nA paragraph with **bold** text.");markdownToStoryblokRichtext() accepts the following parameters:
markdown | A Markdown string to parse. |
|---|---|
options | An optional object with parser configuration. |
The options object accepts the following properties:
resolvers | A partial record of custom node resolvers keyed by node type. |
|---|
getLocalStories()
Section titled “getLocalStories()”getLocalStories(dir);Reads all .json files in the given directory and parses them as Story objects.
import { getLocalStories } from "@storyblok/migrations";
const stories = await getLocalStories(".storyblok/stories/12345");dir | The path to a directory containing story JSON files pulled with the Storyblok CLI. |
|---|
updateLocalStory()
Section titled “updateLocalStory()”updateLocalStory(dir, story);Writes a Story object to a JSON file in the given directory using the naming pattern {slug}_{uuid}.json.
import { getLocalStories, updateLocalStory } from "@storyblok/migrations";
const dir = ".storyblok/stories/12345";const stories = await getLocalStories(dir);stories[0].name = "Updated name";await updateLocalStory(dir, stories[0]);dir | The path to the directory where the story file is written. |
|---|---|
story | A Story object to persist. |
getLocalAssets()
Section titled “getLocalAssets()”getLocalAssets(dir);Reads all .json files in the given directory and parses them as Asset objects.
import { getLocalAssets } from "@storyblok/migrations";
const assets = await getLocalAssets(".storyblok/assets/12345");dir | The path to a directory containing asset JSON files pulled with the Storyblok CLI. |
|---|
updateLocalAsset()
Section titled “updateLocalAsset()”updateLocalAsset(dir, asset);Writes an Asset object to a JSON file in the given directory using the naming pattern {short_filename}_{id}.json.
import { getLocalAssets, updateLocalAsset } from "@storyblok/migrations";
const dir = ".storyblok/assets/12345";const assets = await getLocalAssets(dir);assets[0].alt = "Updated alt text";await updateLocalAsset(dir, assets[0]);dir | The path to the directory where the asset file is written. |
|---|---|
asset | An Asset object to persist. |
getLocalComponents()
Section titled “getLocalComponents()”getLocalComponents(dir);Reads all .json files in the given directory and parses them as Component objects.
import { getLocalComponents } from "@storyblok/migrations";
const components = await getLocalComponents(".storyblok/components/12345");dir | The path to a directory containing component JSON files pulled with the Storyblok CLI. |
|---|
updateLocalComponent()
Section titled “updateLocalComponent()”updateLocalComponent(dir, component);Writes a Component object to a JSON file in the given directory using the naming pattern {name}.json.
import { getLocalComponents, updateLocalComponent } from "@storyblok/migrations";
const dir = ".storyblok/components/12345";const components = await getLocalComponents(dir);components[0].schema.subtitle = { type: "text" };await updateLocalComponent(dir, components[0]);dir | The path to the directory where the component file is written. |
|---|---|
component | A Component object to persist. |
getLocalDatasources()
Section titled “getLocalDatasources()”getLocalDatasources(dir);Reads all .json files in the given directory and parses them as Datasource objects.
import { getLocalDatasources } from "@storyblok/migrations";
const datasources = await getLocalDatasources(".storyblok/datasources/12345");dir | The path to a directory containing datasource JSON files pulled with the Storyblok CLI. |
|---|
updateLocalDatasource()
Section titled “updateLocalDatasource()”updateLocalDatasource(dir, datasource);Writes a Datasource object to a JSON file in the given directory using the naming pattern {slug}_{id}.json.
import { getLocalDatasources, updateLocalDatasource } from "@storyblok/migrations";
const dir = ".storyblok/datasources/12345";const datasources = await getLocalDatasources(dir);datasources[0].name = "Renamed datasource";await updateLocalDatasource(dir, datasources[0]);dir | The path to the directory where the datasource file is written. |
|---|---|
datasource | A Datasource object to persist. |
mapRefs()
Section titled “mapRefs()”mapRefs(story, options);Traverses a story’s content tree and remaps all reference IDs and UUIDs (stories, assets, users, tags, datasources) using the provided lookup maps. The function handles blocks fields, rich text (including embedded blocks and story links), multilink, asset, multiasset, and options fields.
import { type ComponentSchemas, getLocalComponents, mapRefs } from "@storyblok/migrations";
const components = await getLocalComponents(".storyblok/components/12345");
const schemas: ComponentSchemas = {};for (const component of components) { schemas[component.name] = component.schema;}
const { mappedStory, missingSchemas } = mapRefs(story, { schemas, maps: { stories: new Map([[oldStoryId, newStoryId]]), assets: new Map([[oldAssetId, newAssetId]]), },});mapRefs() accepts the following parameters:
story | A Story object whose content references are remapped. |
|---|---|
options | A MapRefsOptions object containing schemas and reference maps. |
The options object accepts the following properties:
schemas | A ComponentSchemas record mapping component names to their schema definitions. |
|---|---|
maps | A RefMaps object containing Map instances for each reference type (stories, assets, users, tags, datasources). |
mapRefs() returns an object with the following properties:
mappedStory | The story with all references remapped. |
|---|---|
processedFields | A Set of component schemas that were processed. |
missingSchemas | A Set of component names for which no schema was found. |
renameDataSourceValue()
Section titled “renameDataSourceValue()”renameDataSourceValue(story, componentsToUpdate, oldValue, newValue);Finds all instances of oldValue in the specified component fields and replaces them with newValue. The function handles both single string values and string arrays.
import { renameDataSourceValue } from "@storyblok/migrations";
const { story: updatedStory, changes } = renameDataSourceValue(story, [{ name: "product_card", field: "category" }], "old-category", "new-category");renameDataSourceValue() accepts the following parameters:
story | A Story object to search for matching values. |
|---|---|
componentsToUpdate | An array of objects, each with a name (component name) and field (field name) property, identifying which fields to update. |
oldValue | The string value to find and replace. |
newValue | The replacement string value. |
renameDataSourceValue() returns an object with the following properties:
story | The updated story with all matching values replaced. |
|---|---|
changes | An array of objects describing each change, with component, field, and path properties. |
deleteOutOfSchemaFields()
Section titled “deleteOutOfSchemaFields()”deleteOutOfSchemaFields(story, schemaDefinition);Recursively walks a story’s content tree and removes any fields that are not present in the given component schema definition.
import { type ComponentSchemas, deleteOutOfSchemaFields, getLocalComponents } from "@storyblok/migrations";
const components = await getLocalComponents(".storyblok/components/12345");
const schemas: ComponentSchemas = {};for (const component of components) { schemas[component.name] = component.schema;}
const { story: cleanedStory, removedFields } = deleteOutOfSchemaFields(story, schemas);deleteOutOfSchemaFields() accepts the following parameters:
story | A Story object to clean. |
|---|---|
schemaDefinition | A ComponentSchemas record mapping component names to their schema definitions. |
deleteOutOfSchemaFields() returns an object with the following properties:
story | The cleaned story with out-of-schema fields removed. |
|---|---|
removedFields | An array of objects, each with a component and field property, describing what was removed. |
ComponentSchemas
Section titled “ComponentSchemas”type ComponentSchemas = Record<string, Record<string, { type: string; source?: string }>>;A type alias representing a record of component schemas. Each key is a component name, and each value is a record of field definitions with type and optional source properties.
MapRefsOptions
Section titled “MapRefsOptions”interface MapRefsOptions { schemas: ComponentSchemas; maps: RefMaps;}The options interface for mapRefs(). Contains the component schemas and the reference maps used for remapping.
RefMaps
Section titled “RefMaps”interface RefMaps { assets?: Map<unknown, string | number>; stories?: Map<unknown, string | number>; users?: Map<unknown, string | number>; tags?: Map<unknown, string | number>; datasources?: Map<unknown, string | number>;}An interface defining lookup maps for each reference type. Each property is an optional Map that maps old reference values to new ones.
Was this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window) . Terms of Service (opens in a new window) apply.
Get in touch with the Storyblok community