Skip to content

Integrate Vue with Storyblok

Use Storyblok to manage the content of your Vue project.

Create a new Vue project in a few simple steps by following the Quick Start page from its official documentation.

If you already have a Storyblok account, go to app.storyblok.com or log in with GitHub to continue.

Create a new blank space (opens in a new window) to follow the tutorial from scratch, or start from the core blueprint (opens in a new window).

In your terminal, cd into your Vue project and install the @storyblok/vue package.

Terminal window
npm install @storyblok/vue

In the root of your project, create a .env file with the access token from your space.

Terminal window
VITE_STORYBLOK_DELIVERY_API_TOKEN="fqc3tdIuC8djNwEYl5cE5Att"

Replace the content of the main.js with the one below:

src/main.js
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');

The Storyblok plugin will make features like fetching, components registration and bridge available across your project.

Create a Home.vue file, with the useStoryblokApi get a client instance to fetch a story’s data.

src/Home.vue
<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.

Replace the content of the App.vue file with the following to render the home view.

src/App.vue
<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.

Create Page.vue component to render all stories of the page content type, such as the home story.

src/components/Page.vue
<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.

src/components/Feature.vue
<script setup>
defineProps({blok: Object})
</script>
<template>
<div class="feature">
<span>{{ blok.name }}</span>
</div>
</template>
src/components/Teaser.vue
<script setup>
defineProps({ blok: Object })
</script>
<template>
<div class="teaser">
<h2>{{ blok.headline }}</h2>
</div>
</template>
src/components/Grid.vue
<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.

src/main.js
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_DELIVERY_API_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.

Terminal window
npm run dev