Storyblok
Search Storyblok's Documentation
  1. Integrate Nuxt with Storyblok

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 component used in the first part of this guide.

Installation

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:

nuxt.config.ts
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.

.env
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.

pages/index.vue
<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.

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.

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.

storyblok/Feature.vue
<script setup>
defineProps({ blok: Object });
</script>

<template>
	<div class="feature">
		<span>{{ blok.name }}</span>
	</div>
</template>
storyblok/Teaser.vue
<script setup>
defineProps({ blok: Object })
</script>

<template>
  <div class="teaser">
    <h2>{{ blok.headline }}</h2>
  </div>
</template>
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.

npm run dev