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.17.4
@storyblok/nuxt@7.0.0
- Node.js v22.13.0
Setup
Create a new Nuxt project in a few simple steps by following the Installation page from its official documentation.
If you don’t already have a Storyblok space, create a starter space at app.storyblok.com, it already comes with initial content and components used in the first part of this guide.
No Storyblok account yet?
Create a Storyblok starter space for free at app.storyblok.com or via GitHub Login. Opens in new tabInstallation
In the terminal, cd
into the Nuxt project and install the @storyblok/nuxt
package.
npm install @storyblok/nuxt@latest
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', {
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