---
title: Integrate Nuxt with Storyblok
description: This guide walks you through integrating Storyblok as a headless CMS, fetching content, and building components to render it effectively in your Nuxt project.
url: https://storyblok.com/docs/guides/nuxt
---

# Integrate Nuxt with Storyblok

Use Storyblok to manage the content of your Nuxt application.

> [!NOTE]
> This guide has been tested with the following package versions:
> 
> -   `nuxt@4.2.2`
> -   `@storyblok/nuxt@9`
> -   Node.js v22.14.0

## Setup

Create a new Nuxt project in a few simple steps by following the [Installation](https://nuxt.com/docs/getting-started/installation) page from its official documentation.

If you already have a Storyblok account, visit [app.storyblok.com](http://app.storyblok.com/#/signup) or [log in with GitHub](https://github.com/login?client_id=Iv23liC8pLXD6VcT2EbS&return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3DIv23liC8pLXD6VcT2EbS%26redirect_uri%3Dhttps%253A%252F%252Fapp.storyblok.com%252F#/login) to continue.

Create a [new blank space](https://app.storyblok.com/#/me/spaces/new?tab=select-plan) to follow the tutorial from scratch, or start from the [core blueprint](https://app.storyblok.com/#/spaces/new/blueprint?blueprintReference=starter).

[Create one and start a free Storyblok space](https://app.storyblok.com/#/signup) No Storyblok account yet?

## Installation

In the terminal, `cd` into the Nuxt project and install the `@storyblok/nuxt` package.

```bash
npm install @storyblok/nuxt
```

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

nuxt.config.ts

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

> [!WARNING]
> Ensure to set the correct `region` value depending on the server location of your Storyblok space. Learn more in the [@storyblok/js package reference](https://www.storyblok.com/docs/libraries/js/js-sdk).

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

.env

```bash
STORYBLOK_DELIVERY_API_TOKEN=<YOUR-ACCESS-TOKEN>
```

> [!NOTE]
> Learn how to get an [access token](/docs/concepts/access-tokens) 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 `app/pages/index.vue` with the `useAsyncStoryblok` to fetch a story’s data.

app/pages/index.vue

```html
<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.

app/storyblok/Page.vue

```html
<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.

> [!TIP]
> 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 (for example, Feature, Teaser, Grid) in it.

Create the code for these components as follows.

app/storyblok/Feature.vue

```html
<script setup>
defineProps({ blok: Object });
</script>

<template>
  <div class="feature">
    <span>{{ blok.name }}</span>
  </div>
</template>
```

app/storyblok/Teaser.vue

```html
<script setup>
defineProps({ blok: Object })
</script>

<template>
  <div class="teaser">
    <h2>{{ blok.headline }}</h2>
  </div>
</template>
```

app/storyblok/Grid.vue

```html
<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.

```bash
npm run dev
```

## Related resources

[Storyblok's Nuxt Blueprint Repository](https://github.com/storyblok/blueprint-core-nuxt)

[@storyblok/nuxt Package Reference](https://www.storyblok.com/docs/libraries/js/nuxt-sdk)

[Concept: Blocks](/docs/concepts/blocks)

[Content Delivery API: Retrieve a Single Story](/docs/api/content-delivery/v2/stories/retrieve-a-single-story)

[Nuxt Docs](https://nuxt.com/)

  

## Pagination

-   [Next: Visual Preview in Nuxt](/docs/guides/nuxt/visual-preview)
