4 min
September 26, 2024
How to Migrate from Wordpress to Storyblok
Moving from one Content Management Platform (CMS) to another can seem like a complicated task. Especially, when going from the popular Wordpress to a more modern and flexible solution like Storyblok. In this article, we'll discuss the key steps of the migration process, as well as a solution to the blog storage problem and the time required for the whole process.
Listen to the audio version of this article.
Preparing for migration
Migrating content from Wordpress to Storyblok requires careful and detailed planning. Start by making a list of all the element that need to be migrated. Examples include: posts, pages, categories, tags, media files, links, and other data.
Exporting data from Wordpress
After you finish preparing, the next step is to export the data from Wordpress directly. Wordpress offers useful tools to export content in XML format, which includes all posts, pages, categories, and other relevant elements.
Note: If you use custom fields, when exporting custom fields and metadata, you need to ensure they are properly migrated.
Importing data into Storyblok
Once the data export from Wordpress is completed, the next step is to import it into Storyblok. This process can be more complicated, because Storyblok has a different data structure from Wordpress.
Our solution includes:
- Data conversion. XML from Wordpress needs to be converted into a format that is compatible with Storyblok, such as JSON or transformed XML (with XSLT).
- Import Content. With Storyblok API, you can import the transformed data. It is important to accurately map the content structure to be compatible with the new system.
Examples
Firstly, you need a story identifier (storyId) and a project identifier (spaceId) to which you want to import the story. Then you will need to make a PUT request and add authorization to the header with your personal access token 0auth (Link) as the value. Last but not least, the request body should contain the story you want to import in this format.
{"data": YOUR_STRINGIFIED_IMPORT_STORY}.
It is important to note that imported stories can only be in JSON or XML format and properly formatted to Storyblok standards.
Import Stories as XML
Endpoint
https://mapi.storyblok.com/v1/spaces/:space_id/stories/:story_id/import.xml
Method
PUT
Header
Authorization: YOUR_OAUTH_TOKEN
Body
{"data": YOUR_IMPORT_XML}
Example
import StoryblokClient from "storyblok-js-client";
const Storyblok = new StoryblokClient({
oauthToken: "YOUR_OAUTH_TOKEN",
});
const spaceId = 134345;
const storyId = 36230141;
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<page text_nodes="0" filename="building-a-food-store" url="posts/building-a-food-store" id="86930141" language="default">
<name>Building a phone store</name>
<tags>
<tag id="69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:image" type="STRING">
<text>
<![CDATA[//a.storyblok.com/f/134445/1500x844/19eeaff370/eeacbea1-99a3-4a96-8ee9-980ae5f9dfe6.jpeg]]>
</text>
</tag>
<tag id="69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:intro" type="STRING">
<text>
<![CDATA[phone stores are important for mankind]]>
</text>
</tag>
<tag id="69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:title" type="STRING">
<text>
<![CDATA[Building a phone store]]>
</text>
</tag>
<tag id="69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:author" type="STRING">
<text>
<![CDATA[cd9f7534-b437-4d3f-b23d-022f464f4cf3]]>
</text>
</tag>
<tag id="69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:richtext:long_text" type="STRING">
<text>
<![CDATA[{"type":"doc","content":[{"type":"paragraph","content":[{"text":"this is a phone store ","type":"text"}]}]}]]>
</text>
</tag>
</tags>
</page>`;
const importXmlStory = async () => {
try {
const response = await Storyblok.put(`spaces/${spaceId}/stories/${storyId}/import.xml`, {
data: xml
});
console.log(response.data);
} catch (error) {
console.error("Error:", error);
}
};
importXmlStory();
Import Stories as JSON
Endpoint
https://mapi.storyblok.com/v1/spaces/:space_id/stories/:story_id/import.json
Method
PUT
Header
Authorization: YOUR_OAUTH_TOKEN
Body
{"data": YOUR_IMPORT_JSON }
Example
import StoryblokClient from "storyblok-js-client";
const Storyblok = new StoryblokClient({
oauthToken: "YOUR_OAUTH_TOKEN",
});
const spaceId = 134345;
const pageId = 36230141;
const authToken = "YOUR_OAUTH_TOKEN";
const json = {
"69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:author": "cd9f7534-b437-4d3f-b23d-022f464f4cf3",
"69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:image": "//a.storyblok.com/f/134445/1500x844/19eeaff370/eeacbea1-99a3-4a96-8ee9-980ae5f9dfe6.jpeg",
"69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:intro": "iphone stores are important for mankind",
"69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:richtext:long_text": '{"type":"doc","content":[{"type":"paragraph","content":[{"text":"this is an iPhone store ","type":"text"}]}]}',
"69c9f9dd-b5e5-4859-a5ee-0bf8a1319c8e:Post:title": "Building an iPhone store",
language: "default",
page: `${pageId}`,
text_nodes: 0,
url: "posts/building-an-iphone-store",
};
const importStory = async () => {
try {
const response = await Storyblok.put(`spaces/${spaceId}/stories/${pageId}/import.json`, {
data: JSON.stringify(json),
});
console.log(response.data);
} catch (error) {
console.error("Error:", error);
}
};
importStory();
Summary
The entire migration process, including exporting, converting data and importing it into Storyblok, can take anywhere from a few hours to a few days, depending on the size and complexity of the blog. The key here is preparation and testing, which can significantly speed up the implementation of the new platform.