@storyblok/nuxt (Version 10.x)
@storyblok/nuxt is Storyblok’s official development for Nuxt applications.
Requirements
Section titled “Requirements”- Nuxt version 4.0 or later
- Node.js LTS (version 22.x recommended)
- Modern web browser (e.g., Chrome, Firefox, Safari, Edge – latest versions)
Installation
Section titled “Installation”Add the package to a project by running this command in the terminal:
npm install @storyblok/nuxt@latestConfiguration
Section titled “Configuration”Import and initialize the SDK using the access token of a Storyblok space.
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({ modules: [ [ "@storyblok/nuxt", { accessToken: "YOUR_ACCESS_TOKEN", apiOptions: { region: "eu", }, }, ], ],});Components
Section titled “Components”Create a Nuxt component for each block defined in Storyblok. Each component will receive a blok prop, containing the content of the block.
<script setup> defineProps({ blok: Object });</script>
<template> <div v-editable="blok"> <h2>{blok.headline}</h2> </div></template>Use <StoryblokComponent> to automatically render nested components.
<script setup> defineProps({ blok: Object });</script>
<template> <main> <StoryblokComponent v-for="currentBlok in blok.body" :key="currentBlok._uid" :blok="currentBlok" /> </main></template>Fetching and rendering
Section titled “Fetching and rendering”In a Nuxt page or component, use the one-liner composable useAsyncStoryblok to fetch a story and render the content with the StoryblokComponent element.
<script setup> const { story } = await useAsyncStoryblok("home", { // asyncData options https://nuxt.com/docs/4.x/api/composables/use-async-data lazy: false, api: { version: "draft", resolve_relations: "featured-articles.posts", }, bridge: { resolveRelations: ["featured-articles.posts"], }, });</script>
<template> <StoryblokComponent v-if="story" :blok="story.content" /></template>storyblok
Section titled “storyblok”Import and initialize the SDK to access and configure all features.
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({ modules: [["@storyblok/nuxt", OPTIONS]],});Alternative syntax:
import { defineNuxtConfig } from "nuxt";
export default defineNuxtConfig({ modules: ["@storyblok/nuxt"], storyblok: OPTIONS,});All options listed in the @storyblok/vue reference are available. The following additional options are available:
| Key | Description | Type |
|---|---|---|
componentsDir |
Define a custom directory other than storyblok as the location of components. |
string |
enableServerMode |
Enables the JavaScript client to be used on the Nitro API server (and disables it from being used client-side). Defaults to false. |
boolean |
enableSudoMode |
See example below. | boolean |
Example: enableSudoMode
Section titled “Example: enableSudoMode”Use it to apply your custom API customizations.
import { apiPlugin, StoryblokVue } from "@storyblok/vue";
export default defineNuxtPlugin(({ vueApp }) => { vueApp.use(StoryblokVue, { accessToken: "<access-token>", enableSudoMode: true, apiOptions: { cache: { type: "custom", custom: { flush() { console.log("done"); }, }, }, }, use: [apiPlugin], });});StoryblokVue
Section titled “StoryblokVue”Import and use StoryblokVue to create a custom Nuxt plugin as shown in the enableSudoMode example above.
useAsyncStoryblok
Section titled “useAsyncStoryblok”Updated in 11.1.4
Using this one-liner composable, enable both data fetching and bridge capabilities. This is the recommended option, as it supports both server-side rendering (SSR) and static site generation (SSG).
<script setup> const { story, error } = await useAsyncStoryblok(URL, { api: API_OPTIONS, bridge: BRIDGE_OPTIONS, });
if (error.value) { throw createError({ statusCode: error.value.statusCode, statusMessage: error.value.statusMessage, }); }</script>The composable takes the story’s full slug and a single options object. Alongside api and bridge, that object accepts any useAsyncData option, such as lazy or watch, and forwards them to useAsyncData.
bridge is optional. Without it, the bridge still registers and inherits resolveRelations and resolveLinks from the resolve_relations and resolve_links values in api. An explicit bridge value takes precedence over that fallback.
The following example omits bridge and still resolves relations during live preview:
<script setup> // The bridge is active and resolves `featured-articles.posts` during live preview. const { story } = await useAsyncStoryblok("home", { api: { version: "draft", resolve_relations: "featured-articles.posts", }, });</script>For the API_OPTIONS, see the storyblok-js-client reference. For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
useStoryblok
Section titled “useStoryblok”Enable both data fetching and bridge capabilities using this composable. Recommended only for client-side rendering (CSR).
<script setup> import {useStoryblok} from '@storyblok/vue'; const {(story, fetchState)} = await useStoryblok(URL, API_OPTIONS, BRIDGE_OPTIONS);</script>For the API_OPTIONS, see the storyblok-js-client reference. For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
useStoryblokApi
Section titled “useStoryblokApi”useStoryblokApi() returns the client instantiated in the application.
<script setup> import { useStoryblokApi } from "@storyblok/nuxt"; const storyblokApi = useStoryblokApi(); const { data } = await storyblokApi.get(URL, API_OPTIONS);</script>For the API_OPTIONS, see the storyblok-js-client reference.
serverStoryblokClient
Section titled “serverStoryblokClient”Get an instance of the Storyblok client for Nitro API Server endpoints with the explicit import #storyblok/server.
import { serverStoryblokClient } from "#storyblok/server";
export default defineEventHandler(async (event) => { const storyblokApi = serverStoryblokClient(event);
const { data } = await storyblokApi.get("cdn/stories/home", { version: "draft", });
return { story: data.story };});useStoryblokBridge
Section titled “useStoryblokBridge”useStoryblokBridge() activates the Storyblok Bridge.
<script setup> import { useStoryblokApi, useStoryblokBridge } from "@storyblok/nuxt";
const storyblokApi = useStoryblokApi(); const { data } = await storyblokApi.get(URL, API_OPTIONS);
onMounted(() => { useStoryblokBridge(STORY_ID, CALLBACK, BRIDGE_OPTIONS); });</script>For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
StoryblokComponent
Section titled “StoryblokComponent”This component automatically renders Storyblok blocks for corresponding Vue components registered in the application. It requires a blok property. Any additional passed properties are forwarded to the Vue component.
<StoryblokComponent :blok="story.content" />Use it to iterate over blocks fields as follows:
<StoryblokComponent v-for="currentBlok in blok.body" :key="currentBlok._uid" :blok="currentBlok" />v-editable
Section titled “v-editable”Use the v-editable directive in components to connect them to the Storyblok Bridge.
<script setup> defineProps({ blok: Object });</script>
<template> <section v-editable="blok"> <h3>{{ blok.name }}</h3> </section></template>StoryblokRichText
Section titled “StoryblokRichText”Used to render a rich text field from a Storyblok story.
<template> <StoryblokRichText :document="blok.richtext_field" /></template>Refer to the Vue StoryblokRichText documentation for full usage, customization options, and TypeScript support.
The Nuxt SDK supports all features, including:
componentscustomizationoptimizeImagesupportuseStoryblokRichTextfor programmatic renderingsplitTableRowsand other utilities
Further resources
Section titled “Further resources”Previous versions
Section titled “Previous versions”Was this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window).Terms of Service (opens in a new window) apply.
Get in touch with the Storyblok community