Integrate Nuxt with Storyblok
Use Storyblok to manage the content of your Nuxt application.
This guide has been tested with the following package versions:
nuxt@3.18.1@storyblok/nuxt@8.0.3- Node.js v22.14.0
Setup
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, go to app.storyblok.com or log in with GitHub to continue.
Create a new blank space to follow the tutorial from scratch, or start from the core blueprint.
No Storyblok account yet?
Create one and start a free Storyblok space Opens in new tabInstallation
In the terminal, cd into the Nuxt project and install the @storyblok/nuxt package.
npm install @storyblok/nuxt@3 In the nuxt.config.ts configuration file, add the Storyblok module:
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
[
'@storyblok/nuxt',
{
accessToken: process.env.STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu',
},
},
],
],
}); Ensure to set the correct region value depending on the server location of your Storyblok space. Learn more in the @storyblok/js package reference.
In the root of your project, create a .env file with the access token from your space.
STORYBLOK_DELIVERY_API_TOKEN=<YOUR-ACCESS-TOKEN> Learn how to get an access token for your Storyblok project.
The Storyblok module will make features like fetching, component registration, and bridge available across your project.
Fetch a single story
Remove app.vue and create a new file pages/index.vue with the useAsyncStoryblok to fetch a story’s data.
<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 and register blocks
Create a Page.vue component to render all stories of the page content type, such as the home story.
<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.
In Nuxt, Pascal-case named components (e.g. ExampleComponent.vue) placed in the storyblok folder will be imported automatically. Learn more in the @storyblok/nuxt package reference.
Stories might contain a body or a similar blocks 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.
Run the server and visit the site in your browser.
npm run dev Next Part
Visual Preview in Nuxt