---
title: @storyblok/migrations (Version 1.x)
description: @storyblok/migrations provides migration utilities for Storyblok.
url: https://storyblok.com/docs/libraries/js/migrations
---

# @storyblok/migrations (Version 1.x)

[@storyblok/migrations](https://github.com/storyblok/monoblok/tree/main/packages/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

-   **Node.js** LTS (version 22.x recommended)

## Installation

Add the package to a project:

```bash
npm install @storyblok/migrations@latest
```

## API

### `urlToLink()`

```ts
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.

```ts
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()`

```ts
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.

```ts
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()`

```ts
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](/docs/libraries/js/rich-text).

```ts
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()`

```ts
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](/docs/libraries/js/rich-text).

```ts
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()`

```ts
getLocalStories(dir);
```

Reads all `.json` files in the given directory and parses them as `Story` objects.

```ts
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](/docs/libraries/storyblok-cli). |
| --- | --- |

### `updateLocalStory()`

```ts
updateLocalStory(dir, story);
```

Writes a `Story` object to a JSON file in the given directory using the naming pattern `{slug}_{uuid}.json`.

```ts
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()`

```ts
getLocalAssets(dir);
```

Reads all `.json` files in the given directory and parses them as `Asset` objects.

```ts
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](/docs/libraries/storyblok-cli). |
| --- | --- |

### `updateLocalAsset()`

```ts
updateLocalAsset(dir, asset);
```

Writes an `Asset` object to a JSON file in the given directory using the naming pattern `{short_filename}_{id}.json`.

```ts
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()`

```ts
getLocalComponents(dir);
```

Reads all `.json` files in the given directory and parses them as `Component` objects.

```ts
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](/docs/libraries/storyblok-cli). |
| --- | --- |

### `updateLocalComponent()`

```ts
updateLocalComponent(dir, component);
```

Writes a `Component` object to a JSON file in the given directory using the naming pattern `{name}.json`.

```ts
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()`

```ts
getLocalDatasources(dir);
```

Reads all `.json` files in the given directory and parses them as `Datasource` objects.

```ts
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](/docs/libraries/storyblok-cli). |
| --- | --- |

### `updateLocalDatasource()`

```ts
updateLocalDatasource(dir, datasource);
```

Writes a `Datasource` object to a JSON file in the given directory using the naming pattern `{slug}_{id}.json`.

```ts
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()`

```ts
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.

```ts
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()`

```ts
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.

```ts
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()`

```ts
deleteOutOfSchemaFields(story, schemaDefinition);
```

Recursively walks a story’s content tree and removes any fields that are not present in the given component schema definition.

```ts
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`

```ts
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`

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

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

### `RefMaps`

```ts
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.

## Pagination

-   [Previous: Rich Text](/docs/libraries/js/rich-text)
-   [Next: Region Helper](/docs/libraries/js/region-helper)
