Quickly transforming JSON Data into Storyblok Content

Published

September 03, 2022

In this post, we will look at how we can quickly transform JSON data into Storyblok Content using the Storyblok Management API. My old blog was set up with Eleventy, which was nice, because it already puts data into nice JSON objects. I wanted to move my blog over to Storyblok, but I didn’t want to manually create all the content. I wrote a quick script to help me with that.

The old JSON Data

The old data was an array of objects that looked like this:

{
  date: '2020-02-23',
  location: 'Remote',
  conference: 'JS World Conference',
  category: 'Talk',
  title: 'Sky’s the limit: Headless eCommerce with Next.js',
  link: 'https://frontenddeveloperlove.com/'
}

Setting up Storyblok

The next step was to set up a similar content structure in Storyblok. I used a pretty standard "Page" setup with multiple bloks. Then I created a new component called "Event" that had the similar fields as the old JSON data. We'll also create one example Event in our Story to use as a template.

Creating the script

The script we'll use to transform the data is written in Node.js. We'll need two libraries storyblok-js-client and uuid. You can install them with npm install storyblok-js-client uuid or use a global installation. Let's create a file transform.js to write our code:

const fs = require('fs')
const StoryblokClient = require('storyblok-js-client')
const { v4 } = require('uuid')

The next step is to retrieve the personal access token from Storyblok. You can find it in your account settings. Then we'll create a new Storyblok client and set the token. We'll also set a config object with our space ID and the storyId. You can retrieve those from the URL if you're editing the story in Storyblok:

  • https://app.storyblok.com/#/me/spaces/12345/stories/0/0/987654321 - space ID is 12345, story ID is 987654321
const Storyblok = new StoryblokClient({
    oauthToken: 'YOUR_PERSONAL_ACCESS_TOKEN' // can be found in your My account section
})

const config = {
    jsonFile: './speaking.json', // the json fiel to read
    spaceId: 'YOUR_SPACE_ID',
    storyId: 'YOUR_STORY_ID',
}

Reading the Story

Now we'll retrieve the story from Storyblok. We'll use the Storyblok.get method to get the content. Then we can log the first event content object to the console to see what we're working with.

async function readStory() {
    const { data } = await Storyblok.get(`spaces/${config.spaceId}/stories/${config.storyId}`)
    console.log("new structure", data.story.content.body[0])
    return data.story
}

Here you can see the new structure of the event object:

{
  _uid: '79befb10-ca3f-43e3-92fa-07c3a60a9d09',
  date: '2022-09-14 12:00',
  website: {
    id: '',
    url: 'www.test.at',
    linktype: 'url',
    fieldtype: 'multilink',
    cached_url: 'www.test.at'
  },
  location: 'remote',
  component: 'Event',
  talk_name: 'The Talk',
  event_name: 'Example',
  event_type: 'Workshop',
  slide_link: 'www.test.at',
  video_link: 'www.test.at'
}

Transforming the old data

Now we'll read the old JSON data from a file. We'll use the fs.readFileSync method to do that. Then we'll map over the array of Events and transform them to the new structure. We'll use the uuid library to generate a unique ID for each event. Comparing the old structure and the new structure, we can now fill the new object with the old data read from the JSON file.

async function transformData() {
    const file = fs.readFileSync(config.jsonFile)
    const speakingEvents = JSON.parse(file);
    // console.log("old structure", speakingEvents[0])

    const newEvents = speakingEvents.map(event => {
        return {
            _uid: v4(),
            date: event.date + ' 12:00',
            website: {
                id: '',
                url: event.link,
                linktype: 'url',
                fieldtype: 'multilink',
                cached_url: event.link,
            },
            location: event.location,
            component: 'Event',
            talk_name: event.title,
            event_name: event.conference,
            event_type: event.category,
            slide_link: event?.slides || '',
            video_link: event?.video || '',
        }
    })
    // console.log("transformed structure", newEvents[0])

    return newEvents
}

Updating the Story

Finally we can put that all together. We'll use the Storyblok.put method to update the Story. First we read the existing story, then we transform the data and overwrite the body property with the new data.

async function main() {
    const story = await readStory()
    const newData = await transformData()
    story.content.body = newData

    Storyblok.put(`spaces/${config.spaceId}/stories/${config.storyId}`, {
        "story": story,
        "force_update": 1,
        "publish": 1
    })
}

Now we just need to call our function:

main()

And then the whole node.js script on the commandline:

node transform.js

And that's it, you can see the full script here.

More articles