@storyblok/nuxt (Version 9.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/api/composables/use-async-data#params 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”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_OPTIONS, BRIDGE_OPTIONS);
if (error.value) { throw createError({ statusCode: error.value.statusCode, statusMessage: error.value.statusMessage }); } }</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 story.
<StoryblokRichText :doc="blok.richtext_field" />See the @storyblok/richtext reference for further details.
Example: Override default resolvers
Section titled “Example: Override default resolvers”<script setup> import { NuxtLink } from '#components'; import type { StoryblokRichTextNode } from '@storyblok/vue'; import CodeBlok from "./components/CodeBlok.vue";
const resolvers = { // NuxtLink example: [MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) => h(NuxtLink, { to: node.attrs?.href, target: node.attrs?.target, }, node.text), // Custom code block component example: [BlockTypes.CODE_BLOCK]: (node: Node) => { return h(CodeBlock, { class: node?.attrs?.class, }, node.children) }, }</script>
<template> <StoryblokRichText :doc="blok.richtext_field" :resolvers="resolvers" /></template>useStoryblokRichText
Section titled “useStoryblokRichText”Use this composable to programmatically render a rich text field.
<script setup> import { useStoryblokRichText } from "@storyblok/nuxt"; const { render } = useStoryblokRichText(RICH_TEXT_OPTIONS);
const content = render(blok.articleContent);</script>
<template> <div v-html="content"></div></template>See the @storyblok/richtext reference for further details.
Example: Override default resolvers
Section titled “Example: Override default resolvers”<script setup> import CodeBlok from "./components/CodeBlok.vue";
const { render } = useStoryblokRichText({ resolvers: { // NuxtLink example: [MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) => h(NuxtLink, { to: node.attrs?.href, target: node.attrs?.target, }, node.text), // Custom code block component example: [BlockTypes.CODE_BLOCK]: (node: Node) => h(CodeBlock, { class: node?.attrs?.class, }, node.children) } });
const root = () => render(blok.articleContent);</script>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. Terms of Service apply.
Get in touch with the Storyblok community