Skip to content

@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.

  • Node.js LTS (version 22.x recommended)

Add the package to a project:

Terminal window
npm install @storyblok/migrations@latest
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:

urlA URL string. Supports https://, http://, and mailto: schemes.
optionsAn optional object with additional link properties.

The options object accepts the following properties:

targetThe link target: '_blank' or '_self'.
titleA title attribute for the link.
relA rel attribute value (e.g., 'noopener').
anchorAn anchor fragment to append to the URL.
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:

urlA URL string pointing to the asset.
optionsAn optional object with additional asset properties.

The options object accepts the following properties:

altAlternative text for the asset.
titleA title for the asset.
copyrightCopyright information.
focusA focal point string.
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:

htmlAn HTML string to parse.
optionsAn optional object with parser configuration.

The options object accepts the following properties:

allowCustomAttributesWhen true, the parser preserves custom HTML attributes.
normalizeWhitespaceWhen true, the parser normalizes whitespace in text nodes.
resolversA record of custom element resolvers keyed by tag name.
styleOptionsAn array of style options for inline style handling.
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:

markdownA Markdown string to parse.
optionsAn optional object with parser configuration.

The options object accepts the following properties:

resolversA partial record of custom node resolvers keyed by node type.
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");
dirThe path to a directory containing story JSON files pulled with the Storyblok CLI.
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]);
dirThe path to the directory where the story file is written.
storyA Story object to persist.
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");
dirThe path to a directory containing asset JSON files pulled with the Storyblok CLI.
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]);
dirThe path to the directory where the asset file is written.
assetAn Asset object to persist.
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");
dirThe path to a directory containing component JSON files pulled with the Storyblok CLI.
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]);
dirThe path to the directory where the component file is written.
componentA Component object to persist.
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");
dirThe path to a directory containing datasource JSON files pulled with the Storyblok CLI.
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]);
dirThe path to the directory where the datasource file is written.
datasourceA Datasource object to persist.
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:

storyA Story object whose content references are remapped.
optionsA MapRefsOptions object containing schemas and reference maps.

The options object accepts the following properties:

schemasA ComponentSchemas record mapping component names to their schema definitions.
mapsA RefMaps object containing Map instances for each reference type (stories, assets, users, tags, datasources).

mapRefs() returns an object with the following properties:

mappedStoryThe story with all references remapped.
processedFieldsA Set of component schemas that were processed.
missingSchemasA Set of component names for which no schema was found.
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:

storyA Story object to search for matching values.
componentsToUpdateAn array of objects, each with a name (component name) and field (field name) property, identifying which fields to update.
oldValueThe string value to find and replace.
newValueThe replacement string value.

renameDataSourceValue() returns an object with the following properties:

storyThe updated story with all matching values replaced.
changesAn array of objects describing each change, with component, field, and path properties.
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:

storyA Story object to clean.
schemaDefinitionA ComponentSchemas record mapping component names to their schema definitions.

deleteOutOfSchemaFields() returns an object with the following properties:

storyThe cleaned story with out-of-schema fields removed.
removedFieldsAn array of objects, each with a component and field property, describing what was removed.
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.

interface MapRefsOptions {
schemas: ComponentSchemas;
maps: RefMaps;
}

The options interface for mapRefs(). Contains the component schemas and the reference maps used for remapping.

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?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window) . Terms of Service (opens in a new window) apply.