Storyblok
Overview
The SCAYLE Storefront Application includes a default integration that allows you to use Storyblok as a CMS. It provides various helpers to quickly introduce custom content into your Storefront Application. In the background, the Storefront Application uses @storyblok/nuxt
. For further details, consult the Storyblok documentation.
Quick links
- Storyblok Developer Guides
- Storyblok Editor Guides
- Storyblok Youtube Walkthrough
Storefront Integration
Local Preview
You can preview your local development environment directly within Storyblok.

Storyblock Local Environment
Product Data
To link content in Storyblok to your shop data, the Storefront Application adds fields in Storyblok that you can then fill with your desired categories and products.

Storyblok Fields for Categories and Products
Ready Components
The following components are implemented as part of the Storefront Application, meaning they are available out-of-the-box for all shops that are built upon this foundation.
Base Storyblok Components
Accordion
AccordionEntry
Banner
BannerLink
ClickableImage
CmsImage
CmsLink
CmsText
CmsVideo
DetailImage
Grid
GridTile
ImageSlider
ImageSliderSlide
ImageText
Page
Product
ProductSlider
ScrollableLinkList
SlideShow
Story
StoryblokLink
Technical Details
The Storyblok integration with the Storefront Application is separated between local development (using Storyblok CLI) and shop runtime (using @storyblok/nuxt
).
Initial Development Setup
To use Storyblok as your CMS, add the following configuration to your nuxt.config.ts
:
export default defineNuxtConfig({
cms: {
provider: 'storyblok'
},
})
The initial setup requires the creation of a dedicated local .env.storyblok
file. This file will contain all Storyblok-relevant environment variables necessary for local development:
STORYBLOK_PERSONAL_TOKEN=<INSERT-YOUR-TOKEN-HERE>
STORYBLOK_SPACE_ID=<INSERT-YOUR-SPACE-ID-HERE>
Additionally, ensure your nuxt.config.ts
is configured to use the access token:
export default defineNuxtConfig({
runtimeConfig: {
cms: {
accessToken: '', // Overide: NUXT_PUBLIC_CMS_ACCESS_TOKEN
},
},
})
- Create a STORYBLOK_PERSONAL_TOKEN: A
STORYBLOK_PERSONAL_TOKEN
can be created as part of the Storyblok Account Settings. - Source the STORYBLOK_SPACE_ID: The
STORYBLOK_SPACE_ID
can be found as part of the URL when logged into storyblok.com and accessing the appropriate Storyblok space.
Scripts
As part of the Storefront Application's package.json
, some additional scripts are included to interact with Storyblok:
storyblok:download
: Downloads the latest component schemas from the respective Storyblok space using the Storyblok CLI.storyblok:generate
: Uses the downloaded components JSON schema and transforms it into TypeScript types (see section "Type Definitions").storyblok:login
: Authenticates your local development environment with the Storyblok CLI.storyblok:unused
: Outputs an overview of used and unused Storyblok components in a space.
While storyblok:download
and storyblok:login
directly utilize the Storyblok CLI, storyblok:generate
and storyblok:unused
execute dedicated .cjs
scripts (scripts/storyblok-generate.cjs
and scripts/storyblok-unused.cjs
respectively).
Type Definitions
storyblok/types/storyblok.d.ts
: Contains manual type definitions.storyblok/types/storyblok.gen.d.ts
: This file is automatically generated by thestoryblok:generate
script based on the local Storyblok components JSON schema. The script uses a custom internal NPM package calledstoryblok-generate-ts
, which provides a configurable transformation function (storyblokToTypescript
) that outputs the type definition based on a pre-configured object.
Local Development Workflow
The process to synchronize a Storefront Application project during local development is identical for both new and existing projects. It primarily involves running the storyblok:download
and storyblok:generate
scripts to fetch content schemas and update local types.
Basic Composables and Helpers
To simplify the usage of certain functionalities with Storyblok components, the SCAYLE Storefront Application includes a few reusable composables and helpers:
storyblok/composables/useCmsAlignment.ts
: Provides Tailwind-compatible alignment classes to be used with Storyblok components.storyblok/composables/useStoryblokImage.ts
: Provides utilities to process and return a sanitized teaser image object for use with Storyblok components.storyblok/composables/useStoryblokMargins.ts
: Provides Tailwind-compatible margin classes to be used with Storyfront components.composables/useCmsListingContent.ts
: Returns a formatted object for usage with listings containing the CMS content,preListingContent
,postListingContent
, andhasTeaserImage
.
Shop Runtime
The runtime integration between Storyblok and the SCAYLE Storefront Application is achieved by using the @storyblok/nuxt
module.
The configuration can be extended under the storyblok
key as part of the nuxt.config.ts
. Refer to the official Storyblok module documentation for more information and configuration options.
The default configuration only sets the STORYBLOK_ACCESS_TOKEN
and enables the bridge
option. The bridge
option is used for integrating with the Nuxt framework and with the Storyblok visual editor.
The integration additionally relies on the @nuxt/image
module (See NuxtImage module documentation) to handle images used with Storyblok components.
Deployment Requirements
The @storyblok/nuxt
module provides an integration with the Nuxt RuntimeConfig functionality. This means that the NUXT_STORYBLOK_ACCESS_TOKEN
can be set during the application's runtime as an environment variable instead of during build time, enhancing deployment flexibility.
Auto-Imported Components
Storyblok components are auto-imported from the storyblok/
directory at the root of the project and are made available throughout the project. Be mindful of component name collisions: if your component in the ~/components
directory is named the same as one inside ~/storyblok
, there can be issues with the Storyblok auto-imported components. The StoryblokComponent
is also auto-imported and can be used out-of-the-box.
Fetching Content
The Storefront Application provides a simple way to fetch content from Storyblok.
useCMS
Composables: TheuseCMS
composable internally relies on thestoryblok-js-client
package to fetch content. As content from Storyblok allows references to data provided by SCAYLE (e.g., product data), the Storefront Application features this composable.useCMS
accepts akey
argument that will be used as auseAsyncData
key for storing values.useCMS
exposes the following two dedicated composables:useCMSBySlug
: Wraps an async function arounduseAsyncData
anduseStoryblokApi
composables to fetch Storyblok content by slug (using the slug formatcdn/stories/${slug}
).useCMSByFolder
: Wraps an async function arounduseAsyncData
anduseStoryblokApi
composables to fetch Storyblok content by folder (using thestarts_with
parameter).
As these composables wrap useAsyncData
, they inherit its full type signature. For more details on all returned data, refer to the Nuxt documentation on Data Fetching.
Example Usage:
import type { SbFooter } from '~/modules/cms/providers/storyblok/types'
import { useCMSBySlug } from '~/modules/cms/providers/storyblok/composables/useCMS'
const props = defineProps<{
slug: string
}>()
const { fetchBySlug } = useCMS(`content-page-${props.slug}`)
const { data, error, status } = await useCMSBySlug<SbContentPage>(
`content-page-${props.slug}`,
`content/${props.slug}`,
)
WWhile the Nuxt 2-based implementation allowed for Storyblok content to be manually cache-controlled, this feature set is currently not available for the Nuxt 3-based implementation.
Live Preview
To display unpublished changes on the initial load within the Storyblok editor, the access token needs the Preview
access level. If the access token has a different access level, unpublished changes will only appear after modifications are made within the editor.
Components
This section offers a detailed overview of various shop areas utilizing Storyblok content, alongside their configuration options. It's essential to review the type definitions (storyblok/types/storyblok.gen.d.ts
) to understand the optional values and the expected data types for each configuration option.
Homepage
Component: SlideShow
Parameter | Details |
---|---|
h1 | String |
slides | SbSlide[] |
margin_top |
Accepts |
Component: Slide
Parameter | Details |
---|---|
image | SbCmsImage | SbVideo |
topline | String |
headline | String |
cta_label | String |
cta_url | String |
is_dark | Boolean |
align |
Accepts |
justify |
Accepts |
Component: ImageSlider
Parameter | Details |
---|---|
image | SbCmsImage | SbVideo |
headline | String |
cta_label | String |
cta_url | String |
slides | SbImageSliderSlide[] |
margin_top |
Accepts |
Component: ImageSliderSlide
Parameter | Details |
---|---|
image | SbCmsImage | SbVideo |
topline | String |
headline | String |
is_new | Boolean |
cta_label | String |
cta_url | String |
item_id | String |
item_name | String |
promotion_id | String |
promotion_name | String |
creative_name | String |
creative_slot | String |
Component: Grid
Parameter | Details |
---|---|
margin_top |
Accepts |
is_containered | Boolean |
is_containered_desktop | Boolean |
is_spaced | Boolean |
columns | SbShopableImage |
Component: GridTile
- Options:
headline
: accepts a stringcta
: accepts a stringcta_link
: accepts a link
Parameter | Details |
---|---|
content | SbShopableImage |
headline | String |
cta | String |
cta_link | Sbmultilink |
Component: ImageText
Parameter | Details |
---|---|
image |
Accepts |
image | SbCmsImage[] |
topline | String |
headline | String |
text | String |
cta | String |
cta_link | Sbmultilink |
justify |
Accepts |
Component: ProductSlider
Parameter | Details |
---|---|
headline | String |
cta_label | String |
cta_url | String |
product_ids |
References to SCAYLE products |
margin_top |
Accepts |
Component: Banner
Parameter | Details |
---|---|
is_active | Boolean |
type |
Accepts |
body | String |
countdown_until | String |
links | SbBannerLink[] |
item_id | String |
item_name | String |
promotion_id | String |
promotion_name | String |
creative_name | String |
creative_slot | String |
location_id | String |
index | String |
cta_url | Sbmultilink |
Component: Story
Parameter | Details |
---|---|
color | String |
image | Sbasset |
label | String |
cta_url | String |
Footer
Component: Footer
Parameter | Details |
---|---|
text | Richtext |
align_right | Boolean |
link_groups | SbLinkGroup[] |
text_bottom | String |
social_media | SbSocialMediaLink[] |
Component: LinkGroup
Parameter | Details |
---|---|
title | String |
links | SbLink[] |
Component: Link
Parameter | Details |
---|---|
label | String |
cta_url | Sbmultilink |
open_in_new_tab | Boolean |
Listing Pages
Component: ListingPage
Parameter | Details |
---|---|
teaser_image | Sbasset |
teaser_image_mobile | Sbasset |
pre_listing_content | SbAccordion | SbAccordionEntry | SbBanner | SbBannerLink | SbClickableImage | SbCmsImage | SbCmsText | SbContentPage | SbDetailImage | SbDoubleColumn | SbFooter | SbGrid | SbGridTile | SbImageSlider | SbImageSliderSlide | SbImageText | SbLink | SbLinkGroup | SbListingPage | SbPage | SbParagraph | SbProduct | SbProductSlider | SbShopableImage | SbSlide | SbSlideShow | SbSocialMediaLink | SbStory | SbTitle | SbVideo |
SEO |
|
title: string | |
plugin?: string | |
og_image?: string | |
og_title?: string | |
description?: string | |
twitter_image?: string | |
twitter_title?: string | |
og_description?: string | |
twitter_description?: string | |
} | |
post_listing_content | SbAccordion | SbAccordionEntry | SbBanner | SbBannerLink | SbClickableImage | SbCmsImage | SbCmsText | SbContentPage | SbCustomerServiceInfo | SbDetailImage | SbDoubleColumn | SbFooter | SbGrid | SbGridTile | SbImageSlider | SbImageSliderSlide | SbImageText | SbLink | SbLinkGroup | SbListingPage | SbPage | SbParagraph | SbProduct | SbProductSlider | SbShopableImage | SbSlide | SbSlideShow | SbSocialMediaLink | SbStory | SbTitle | SbVideo |
Service Pages
Component: Accordion
- Options:
has_link_list
: accepts a booleanentries
: accept a list ofSbAccordionEntry
margin_top
: accepts a string
Parameter | Details |
---|---|
has_link_list | Boolean |
entries | SbAccordionEntry [] |
margin_top |
Accepts |
Component: AccordionEntry
Parameter | Details |
---|---|
title | String |
link_title | String |
body | Richtext |
Area: Content Pages
Component: Content Page
Parameter | Details |
---|---|
teaser_image | Sbasset |
teaser_image_mobile | Sbasset |
headline | String |
subline | String |
content | SbCmsImage | SbCmsText | SbGrid | SbImageSlider | SbProductSlider | SbSlideShow | SbSocialMediaLink | SbVideo | SbAccordion | SbCustomerServiceInfo | SbDoubleColumn | SbParagraph |
SEO |
|
title: string | |
plugin?: string | |
og_image?: string | |
og_title?: string | |
description?: string | |
twitter_image?: string | |
twitter_title?: string | |
og_description?: string | |
twitter_description?: string | |
} | |
All Pages
Component: Video
Parameter | Details |
---|---|
control_color | String |
-autoplay | Boolean |
has_controls | Boolean |
is_containered | Boolean |
video | Sbasset |
preview_desktop_image | Sbasset |
preview_mobile_image | Sbasset |
loop | Boolean |
item_id | String |
item_name | String |
promotion_id | String |
promotion_name | String |
creative_name | String |
creative_slot | String |
location_id | String |
margin_top |
Accepts |
Component: ClickableImage
Parameter | Details |
---|---|
image | SbCmsImage[] |
cta_url | Sbmultilink |
item_id | String |
item_name | String |
promotion_id | String |
promotion_name | String |
creative_name | String |
creative_slot | String |
location_id | String |
margin_top |
Accepts |
Component: CmsImage
Parameter | Details |
---|---|
desktop_image | Sbasset |
mobile_image | Sbasset |
item_id | String |
item_name | String |
promotion_id | String |
promotion_name | String |
creative_name | String |
creative_slot | String |
location_id | String |
index | String |
Component: CmsText
Parameter | Details |
---|---|
body | Richtext |
Component: DoubleColumn
Parameter | Details |
---|---|
column_right | SbAccordion | SbAccordionEntry | SbBanner | SbBannerLink | SbClickableImage | SbCmsImage | SbCmsText | SbContentPage | SbDetailImage | SbDoubleColumn | SbFooter | SbGrid | SbGridTile | SbImageSlider | SbImageSliderSlide | SbImageText | SbLink | SbLinkGroup | SbListingPage | SbPage | SbParagraph | SbProduct | SbProductSlider | SbShopableImage | SbSlide | SbSlideShow | SbSocialMediaLink | SbStory | SbTitle | SbVideo |
column_left | SbAccordion | SbAccordionEntry | SbBanner | SbBannerLink | SbClickableImage | SbCmsImage | SbCmsText | SbContentPage | SbCustomerServiceInfo | SbDetailImage | SbDoubleColumn | SbFooter | SbGrid | SbGridTile | SbImageSlider | SbImageSliderSlide | SbImageText | SbLink | SbLinkGroup | SbListingPage | SbPage | SbParagraph | SbProduct | SbProductSlider | SbShopableImage | SbSlide | SbSlideShow | SbSocialMediaLink | SbStory | SbTitle | SbVideo |
margin_top |
Accepts |
Component: Paragraph
Parameter | Details |
---|---|
headline | String |
cta | Sbmultilink |
body | Richtext |
sub_title | String |
image | Sbmultiasset |