Integrate Vue with Storyblok
Use Storyblok to manage the content of your Vue project.
This guide has been tested with the following package versions::
vue@3.5
vue-router@4.5
@storyblok/vue@8.2
- Node.js v22.13.0
Setup
Create a new Vue project in a few simple steps by following the Quick Start page from its official documentation.
Use the npm create vue
command and opt-out of all optional add-ons.
If you don’t already have a Storyblok space, create a starter space at app.storyblok.com, it already comes with initial content and component we will use in this first part of the guide.
Installation
In your terminal, cd
into your Vue project and install the @storyblok/vue
package.
npm install @storyblok/vue
In the root of your project, create a .env
file with the access token from your space.
VITE_STORYBLOK_DELIVERY_API_TOKEN="fqc3tdIuC8djNwEYl5cE5Att"
Learn how to get an access token for your Storyblok project.
Replace the content of the main.js
with the one below:
import { createApp } from 'vue';
import { StoryblokVue, apiPlugin } from '@storyblok/vue';
import App from './App.vue';
const app = createApp(App);
app.use(StoryblokVue, {
accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu', // Choose the correct region from your Space.
},
use: [apiPlugin],
});
app.mount('#app');
Ensure to set the correct region
value depending on the server location of your Storyblok space. Learn more in the @storyblok/js package reference.
The Storyblok plugin will make features like fetching, components registration and bridge available across your project.
Fetch a single story
Create a Home.vue
file, with the useStoryblokApi
get a client instance to fetch a story’s data.
<script setup>
import { useStoryblok } from '@storyblok/vue';
const story = await useStoryblok('home', {
version: 'draft',
});
</script>
<template>
<StoryblokComponent v-if="story" :blok="story.content" />
</template>
This page fetches the home story of your Storyblok space using the convenient useStoryblok
composable.
The StoryblokComponent
dynamically renders content type and nestable blocks. In this case, it looks for the content type block of the home story.
This element detects the content type of the story for you, in this case page
and look for a component of the same name to render the story. Learn more in the Storyblok Vue package reference.
Replace the content of the App.vue
file with the following to render the home view.
<script setup>
import Home from './Home.vue';
</script>
<template>
<main>
<Suspense>
<template #default>
<Home />
</template>
</Suspense>
</main>
</template>
Suspense
allows the usage of top-level await
syntax inside scripts, like in the Home.vue
file to fetch the story data.
Learn more about the Suspense experimental feature.
Create and register blocks
Create Page.vue
component to render all stories of the page
content type, such as the home story.
<script setup>
defineProps({ blok: Object })
</script>
<template>
<StoryblokComponent v-for="currentBlok in blok.body":key="currentBlok._uid" :blok="currentBlok" />
</template>
Using StoryblokComponent
iterate through the body
field and render the blocks in it.
Stories might contain a body
or similar field which consists of an array with several blocks of custom types (e.g. Feature, Teaser, Grid) in it.
Create the code for these components as follows.
<script setup>
defineProps({blok: Object})
</script>
<template>
<div class="feature">
<span>{{ blok.name }}</span>
</div>
</template>
<script setup>
defineProps({ blok: Object })
</script>
<template>
<div class="teaser">
<h2>{{ blok.headline }}</h2>
</div>
</template>
<script setup>
defineProps({blok: Object})
</script>
<template>
<div class="grid">
<StoryblokComponent v-for="currentBlok in blok.columns":key="currentBlok._uid" :blok="currentBlok" />
</div>
</template>
Similar to Page.vue
, Grid.vue
iterates over the columns
block field.
Add all these new components to your app within the main.js
file.
import { createApp } from 'vue';
import { StoryblokVue, apiPlugin } from '@storyblok/vue';
import App from './App.vue';
import Teaser from './components/Teaser.vue';
import Grid from './components/Grid.vue';
import Feature from './components/Feature.vue';
const app = createApp(App);
app.use(StoryblokVue, {
accessToken: import.meta.env.VITE_STORYBLOK_ACCESS_TOKEN,
use: [apiPlugin],
});
app.component('Teaser', Teaser);
app.component('Grid', Grid);
app.component('Feature', Feature);
app.mount('#app');
Run the server and visit the site in your browser.
npm run dev
Related links
- Storyblok's Vue blueprint repository
- Storyblok Vue package
- Blocks documentation
- Vue documentation
- Content Deliver API - Retrieve a Single Story
Next Part
Visual Preview in Vue