If you've not worked with Storyblok before: go away. Do it. Supplement your technological arsenal with something unexpectedly fantastic. You won't regret it, I promise. I thoroughly recommend it.
I've given a very, very brief description below of what Storyblok is and what it does well. This article looks specifically, however, at the Storyblok Bridge and how to configure it in Typescript, as opposed to Javascript. As such, the article assumes you have a project set up and simply need to convert the JavaScript boilerplate code into TypeScript.
Now that the introductory waffle is out of the way, I welcome you, weary traveller. Come share the warmth of my Mac as it tries to join a Teams meeting. Stay a while and rest, and I shall tell you the tale... of the Storyblok Bridge.
What is Storyblok?
Storyblok is a Headless CMS that structures its content as Bloks - reusable components containing fields (i.e. text, image, markdown, another Blok, etc) - that can be inserted into a page and edited at will.
What makes Storyblok special, however, is its Live Editor. Unlike any other CMS, changes made to the content are visible on the webpage as they happen.
That's right: thanks to the power of the Storyblok Bridge, we can see these changes happening right in front of our eyes.
I could warble away about the wonders of Storyblok for time immemorial but I shall digress for now. After all, your content editors will not write any code but we will. That's why you're here after all!
The Code
A project that I worked on recently leveraged Storyblok with Nuxt.js. As you can imagine, the concept of Bloks (reusable components) lends itself very well to Vue and thus Nuxt. However, this is not a tutorial about how to make that kind of project; Storyblok has several of their own. They even offer starter code for a lot of frameworks!
The boilerplate code for Nuxt, however, is written in JavaScript. So what if we don’t want JavaScript? What if we want her stricter, stronger cousin?
TypeScript Storyblok Bridge
Ta da! A Storyblok Bridge connection made with TypeScript:
As you can see, the code performs exactly the same as it would in JavaScript. It has no extra or different functionality but is simply a less error-prone version.
Let's dive deeper.
Exploring the Code
Vue 3.0 and the Composition API
The TypeScript code makes use of the Composition API from Vue 3.0. One of these is the Ref function. You can see this is imported with the Vue 3.0 lifecycle hooks at the top of the file:
import { defineComponent, useFetch, useContext, ref, onMounted } from '@nuxtjs/composition-api'
onMounted
and $storybrige.on()
The onMounted function is where most of the functionality occurs. Within this, we're calling the $storybridge.on()
function.
app.$storybridge.on('input', (event: StoryblokEventPayload)...
This acts like a listener for events, of the type StoryblokEventPayload
.
StoryblokEventPayload
The StoryblokEventPayload
type is an interface exposed through the index.d.ts
file that can be found in the Storyblok-Nuxt module. This file is imported at the top of the script tag.
import 'storyblok-js-client/dist/index'
You can view this file for yourself by navigating to the storyblok-nuxt
folder within node_modules
and looking in the dist
directory.
Detecting Changes
Within the $storybridge.on()
function, we're detecting an event such as input
, published
, or change
, and then handling the action accordingly.
Input
When detecting any form of input
, we're testing whether the event ID of our project's content matches the event ID of the changed content on Storyblok. If this is true, then the two contents are matched up.
if (event.story.id === story.value.id) {
story.value.content = event.story.content
}
Change or Published
If the changes are saved or 'published', then we force a reload of the currentRoute
to manually refresh and update our view to the latest version.
app.$nuxt.$router.go({
path: app.$nuxt.$router.currentRoute,
force: true
})
Conclusion
And that's it! There was a bit of head-scratching about the what type to make some of this code, specifically the StoryblokEventPayload
event. We also had some fun with getters when accessing the value of the story
ref, using the new Composition API.
However, this code will now hopefully help anyone in a similar predicament and save you some time too.
Storyblok possesses a multitude of great features for both little and large scale projects. I've listed a few down below, and I seriously recommend that you check them out if you're able. They're doing some pretty awesome things.
Cool Storyblok Features
- Live Editor
- Image Service (Through their Image API, a 3.5MB image was passed to my app as a ridiculously tiny 25KB image and then automatically cached, improving page load speeds insurmountably).
- Support for many, many frameworks
- They are a huge backer of VueJS
- Custom plugins (You can customise a Blok's fields entirely to your specifications. Imagine a custom built dropdown menu populated with options FETCHed from an API).
If this is helpful, please let me know with a comment or by reaching out on Twitter. I'd love to see what you're creating with Storyblok, especially if this code has been useful to you.
Top comments (0)