
Live Demo
If you are in a hurry, check out our official live demo on Stackblitz.
🚀 Usage
Note: This module is for Nuxt 3. Check out @storyblok/nuxt-2
for Nuxt 2.
If you are first-time user of the Storyblok, read the Getting Started guide to get a project ready in less than 5 minutes.
Installation
Install @storyblok/nuxt
:
npm install @storyblok/nuxt# yarn add @storyblok/nuxt
Add following code to modules section of nuxt.config.js
and replace the accessToken with API token from Storyblok space.
import { defineNuxtConfig } from "nuxt";export default defineNuxtConfig({ modules: [ ["@storyblok/nuxt", { accessToken: "<your-access-token>" }] // ... ]});
You can also use the storyblok
config if you prefer:
import { defineNuxtConfig } from "nuxt";export default defineNuxtConfig({ storyblok: { accessToken: "<your-access-token>" }});
Options
When you initialize the module, you can pass all @storyblok/vue options plus a useApiClient
option. For spaces created in the United States, you have to set the region
parameter accordingly { apiOptions: { region: 'us' } }
.
// Defaults["@storyblok/nuxt", { { accessToken: "<your-access-token>", bridge: true, apiOptions: {}, // storyblok-js-client options useApiClient: true }}]
Getting started
1. Creating and linking your components to Storyblok Visual Editor
To link your Vue components to their equivalent you created in Storyblok:
- First, you need to load them globally. You can just place them on the
~/storyblok
directory and will be discovered automagically, otherwise you set another directory can load them manually (for example, by using a Nuxt plugin). - For each components, use the
v-editable
directive on its root element, passing theblok
property that they receive:
<div v-editable="blok" / >
- Finally, use
<StoryblokComponent>
which is available globally in the Nuxt app:
<StoryblokComponent :blok="blok" />
The
blok
is the actual blok data coming from Storblok's Content Delivery API.
2. Getting Storyblok Stories and listen to Visual Editor events
Composition API
The simplest way is by using the useAsyncStoryblok
one-liner composable (it's autoimported) and passing as a first parameter a name of your content page from Storyblok (in this case, our content page name is vue
, by default you get a content page named home
):
<script setup> const story = await useAsyncStoryblok("vue", { version: "draft" });</script><template> <StoryblokComponent v-if="story" :blok="story.content" /></template>
Which is the short-hand equivalent to using useStoryblokApi
inside useAsyncData
and useStoryblokBridge
functions separately:
<script setup> const story = ref(null); const storyblokApi = useStoryblokApi(); const { data } = await useAsyncData( 'vue', async () => await storyblokApi.get(`cdn/stories/vue`, { version: "draft" }) ); story.value = data.value.data.story; onMounted(() => { useStoryblokBridge(story.value.id, (evStory) => (story.value = evStory)); });</script><template> <StoryblokComponent v-if="story" :blok="story.content" /></template>
Using
useAsyncData
SSR and SSG capabilities are enabled.
Rendering Rich Text
You can easily render rich text by using the renderRichText
function that comes with @storyblok/nuxt
and a Vue computed property:
<template> <div v-html="articleContent"></div></template><script setup> const props = defineProps({ blok: Object }) const articleContent = computed(() => renderRichText(blok.articleContent));</script>
You can also set a custom Schema and component resolver by passing the options as the second parameter of the renderRichText
function:
<script setup> import cloneDeep from 'clone-deep' const mySchema = cloneDeep(RichTextSchema) // you can make a copy of the default RichTextSchema // ... and edit the nodes and marks, or add your own. // Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/v4/source/schema.js const props = defineProps({ blok: Object }) const articleContent = computed(() => renderRichText(props.blok.articleContent, { schema: mySchema, resolver: (component, blok) => { switch (component) { case 'my-custom-component': return `<div class="my-component-class">${blok.text}</div>` default: return 'Resolver not defined' } }, }) )</script>
API
useAsyncStoryblok(slug, apiOptions, bridgeOptions)
(Recommended Option) Use useAsyncData
and useState
under the hood for generating SSR or SSG applications.
Check the available apiOptions (passed to storyblok-js-client
) and bridgeOptions (passed to the Storyblok Bridge).
useStoryblok(slug, apiOptions, bridgeOptions)
It could be helpful to use useStoryblok
instead of useAsyncStoryblok
when we need to make client-side requests, for example, getting personalized data for a logged user.
Check the available apiOptions (passed to storyblok-js-client
) and bridgeOptions (passed to the Storyblok Bridge).
useStoryblokApi()
Returns the instance of the storyblok-js-client
.
useStoryblokBridge(storyId, callback, bridgeOptions)
Use this one-line function to cover the most common use case: updating the story when any kind of change happens on Storyblok Visual Editor.
đź”— Related Links
- Live Demo on Stackblitz
- Nuxt.js Hub: Learn how to develop your own Nuxt.js applications that use Storyblok APIs to retrieve and manage content;
- Storyblok & Nuxt.js on GitHub: Check all of our Nuxt.js open source repos;
- Storyblok CLI: A simple CLI for scaffolding Storyblok projects and fieldtypes.
ℹ️ More Resources
Support
- Bugs or Feature Requests? Submit an issue;
- Do you have questions about Storyblok or you need help? Join our Discord Community.
Contributing
Please see our contributing guidelines and our code of conduct. This project use semantic-release for generate new versions by using commit messages and we use the Angular Convention to naming the commits. Check this question about it in semantic-release FAQ.