If you are in a hurry, check out our official live demo on Stackblitz.
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.
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({
modules: ["@storyblok/nuxt"],
storyblok: {
accessToken: "<your-access-token>"
}
});
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
}
}]
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.
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.
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>
(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).
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).
Returns the instance of the storyblok-js-client
.
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.
- 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.
-
Bugs or Feature Requests? Submit an issue;
-
Do you have questions about Storyblok or you need help? Join our Discord Community.
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.