Skip to content

Integrate Nuxt with Storyblok

Use Storyblok to manage the content of your Nuxt application.

Create a new Nuxt project in a few simple steps by following the Installation page from its official documentation.

If you already have a Storyblok account, visit 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 the terminal, cd into the Nuxt project and install the @storyblok/nuxt package.

Terminal window
npm install @storyblok/nuxt

In the nuxt.config.ts configuration file, add the Storyblok module:

nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
[
'@storyblok/nuxt',
{
accessToken: process.env.STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu',
},
},
],
],
});

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

.env
STORYBLOK_DELIVERY_API_TOKEN=<YOUR-ACCESS-TOKEN>

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

Remove app.vue and create a new file app/pages/index.vue with the useAsyncStoryblok to fetch a story’s data.

app/pages/index.vue
<script setup>
const { story } = await useAsyncStoryblok('home', {
api: {
version: 'draft', // or 'published'
},
});
</script>
<template>
<StoryblokComponent v-if="story" :blok="story.content" />
</template>

The StoryblokComponent dynamically renders content type and nestable blocks. In this case, it looks for the content type block of the home story.

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

app/storyblok/Page.vue
<script setup>
defineProps({ blok: Object });
</script>
<template>
<main v-editable="blok">
<StoryblokComponent
v-for="currentBlok in blok.body"
:key="currentBlok._uid"
:blok="currentBlok"
/>
</main>
</template>

Using StoryblokComponent, iterate through the body field and render the blocks in it.

Stories might contain a body or a similar blocks field which consists of an array with several blocks of custom types (for example, Feature, Teaser, Grid) in it.

Create the code for these components as follows.

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

Run the server and visit the site in your browser.

Terminal window
npm run dev

Was this page helpful?

What went wrong?

This site uses reCAPTCHA and Google's Privacy Policy. Terms of Service apply.