Contentful
Introduction
Contentful is a headless CMS platform that you can use out-of-the-box with Storefront Boilerplate. For more information on the features of Contentful itself, refer to the official Contentful documentation.
Storefront Integration
The Contentful integration with SCAYLE Storefront Boilerplate can be separated by concerns of local development (using contentful-cli
) and shop runtime (using contentful Delivery API).
Initial dev setup
The initial setup of Contentful within the SCAYLE Storefront Boilerplate requires the creation of a dedicated local .env.contentful
file. The local .env.contentful
will contain all Contentful-relevant environment variables to be able to work Contentful Management API.
CONTENTFUL_MANAGEMENT_TOKEN=
CONTENTFUL_SPACE_ID=
Create a CONTENTFUL_MANAGEMENT_TOKEN
A CONTENTFUL_MANAGEMENT_TOKEN can be created as part of the Contentful account settings. For more information on creating your Contentful management token, see here.
Source the CONTENTFUL_SPACE_ID
The CONTENTFUL_SPACE_ID can be found in general settings once you are logged into Contentful. For more information on finding your Contentful space ID, see here.
Scripts
As part of the Storefront Boilerplate package.json, some additional scripts are included to interact with Contentful.
contentful:download
- Downloads the information from Contentful
- Uses contentful-export to download all data from the respective Contentful space. You can modify it as needed.
- Data will be stored in
contentful.{SPACE_ID}.json
inside the root dir of your app.
contentful:generate
- Running this command will give you all type definitions from your
contentful.{SPACE_ID}.json
as well as some type guard functions - Uses cf-content-types-generator to generate types
- This will be generated inside of
./modules/cms/providers/contentful/types/gen
Type Definitions
Manual type definition:
./modules/cms/providers/contentful/types/contentful-defs.d
Generated type definition:
./modules/cms/providers/contentful/types/gen/*
Shop Runtime Integration
The runtime integration between Contentful and Storefront Boilerplate uses the Contentful Content Delivery API.
To use Contentful with Storefront Boilerplate, we need to set the CMS provider to Contentful:
export default defineNuxtConfig({
cms: {
provider: 'contentful',
},
})
To have access to the Contentful Content Delivery API, we need to provide an accessToken and spaceID. We'll define it like so:
NUXT_PUBLIC_CMS_ACCESS_TOKEN=
NUXT_PUBLIC_CMS_SPACE=
After adding environment variables to your .env
, your integration is complete. You can also modify your accessToken
and space
in runtimeConfig like so:
export default defineNuxtConfig({
runtimeConfig: {
public: {
cms: {
accessToken: '', // Overide: NUXT_PUBLIC_CMS_ACCESS_TOKEN
space: '', // Overide: NUXT_PUBLIC_CMS_SPACE
},
},
},
})
The integration additionally relies on the @nuxt/image
module (see the NuxtImage module documentation) to handle images used with Contentful components.
Live Preview
The Preview Delivery API is used during the initial load to display unpublished changes in the Contentful editor. To accomplish this, an additional preview access token is required. Without it, unpublished changes will only be visible after they are published in the editor.
export default defineNuxtConfig({
runtimeConfig: {
public: {
cms: {
accessToken: '', // Overide: NUXT_PUBLIC_CMS_ACCESS_TOKEN
previewAccessToken: '', // Overide: NUXT_PUBLIC_CMS_PREVIEW_ACCESS_TOKEN
space: '', // Overide: NUXT_PUBLIC_CMS_SPACE
},
},
},
})
When setting up the preview URL's within Contentful, also add the query param ?_editorMode={entry.sys.updatedAt}
to the URL. This action informs the site to bypass the cache and load Contentful's live preview SDK seamlessly.
Deployment Requirements
Our implementation provides integration with the Nuxt RuntimeConfig functionality. This means that the NUXT_PUBLIC_CMS_ACCESS_TOKEN
, as well as NUXT_PUBLIC_CMS_SPACE
be set during the application's runtime as an environment variable instead of during build time.
Auto-imported components
Contentful components are auto-imported from the ~/modules/cms/providers/contentful/components
directory so components are made available throughout the project. To be mindful of component name collisions we added the prefixCMS
to every component .
Ready Components
The following components are implemented as part of the Storefront Boilerplate, which means they are available out-of-the-box for all shops that are scaffolded from the Storefront Boilerplate - that is, all SCAYLE shops.
Base Contentful Components:
Accordion
AccordionEntry
Banner
BannerLink
ClickableImage
Image
Link
Text
Video
DetailImage
Grid
GridTile
ImageSlider
ImageSliderSlide
ImageText
Page
Product
ProductSlider
ScrollableLinkList
SlideShow
Story
ContentfulLink
The current implementation will add 'CMS'
prefix to every component so when you are using components inside of a template you should use:
<CMSImage
...(props)
></CMSImage>
Default usage within Storefront Boilerplate
The following section contains an overview of all shop areas, that use Contentful content and their options.
For an actual reference which values are optional and what value types are expected for each option, check the type definition!
Fetching content
Storefront Boilerplate provides simple ways to fetch content from Contentful.
useCMS()
As content from Contentful allows references to data provided by SCAYLE, for example product data, Storefront Boilerplate features the useCMS
composable. This composable internally relies on the contentful
package to fetch content from Contentful.
An example usage for getting relevant content might look as follows:
const {
data, status,
} = useCMSBySlug<TypeContentPageSkeleton>(
`content-page-${props.slug}`,
{
content_type: 'contentPage',
'fields.slug[match]': `content/${props.slug}`,
},
)
The composable exposes the following data and functions as dedicated composables:
useCMSBySlug
- Wraps around Nuxt's
useAsyncData
function using thecontentful
package to fetch Contentful content by slug using the slug format - user-friendly and URL-friendly string used to identify and reference a specific piece of content. - NOTE: Entry you are fetching must have field slug and value that you want to fetch
- Wraps around Nuxt's
useCMSByFolder
- Wraps around Nuxt's
useAsyncData
function using thecontentful
package to fetch Contentful content by slug using the slug format - user-friendly and URL-friendly string used to identify and reference a specific piece of content. - NOTE: The Contentful entry you are fetching must have a slug field and value that starts with the slug you want to fetch.
- Wraps around Nuxt's
defaultCMSOptions
- Returns default options for fetching options locale, env, etc.
Composables
Basic composables and helpers to simplify the usage of certain functionalities with Contentful components.
Storefront Boilerplate includes a few simple reusable composables and helpers:
useCMSAligment()
Provides Tailwind-compatible alignment classes to be used with Contentful components
useContentfulImage()
Provides utilities process and return a sanitized teaser image object to be used with Contentful components
useContentfulMargins()
Provides Tailwind-compatible margin classes to be used with Contentful components
useCMSListingContent()
Returns a formatted object for usage with listings containing the CMS content, preListingContent, postListingContent and hasTeaserImage
Components
The following section contains an overview of all shop areas, that use Contentful content and their options.
For an actual reference which values are optional and what value types are expected for each option, check the type definition!
Homepage
Component: SlideShow
Parameter | Details |
---|---|
uid? | string |
h1? | string |
slides? | TypeSlideSkeleton |
marginTop? | TypeMarginSkeleton |
Component: Slide
Parameter | Details |
---|---|
uid? | string |
image? | TypeImageSkeleton | TypeVideoSkeleton |
topline? | string |
headline? | string |
ctaLabel? | string |
ctaUrl? | string |
isDark? | boolean |
align? | 'center' | 'end' | 'start' |
justify? | 'center' | 'end' | 'start' |
Component: ImageSlider
Parameter | Details |
---|---|
uid? | string |
headline? | string |
ctaLabel? | string |
ctaUrl? | string |
slides? | TypeImageSliderSlideSkeleton[] |
marginTop? | TypeMarginSkeleton |
Component: ImageSliderSlide
Parameter | Details |
---|---|
uid? | string |
image? | Asset |
topline? | string |
headline? | string |
isNew? | boolean |
ctaLabel? | string |
ctaUrl? | string |
tracking? | TypeTrackingSkeleton |
Component: Grid
Parameter | Details |
---|---|
uid? | string |
marginTop? | TypeMarginSkeleton |
isContainered? | boolean |
isContaineredDesktop? | boolean |
isSpaced? | boolean |
columns? | TypeClickableImageSkeleton | TypeCmsTextSkeleton | TypeGridTileSkeleton | TypeImageSkeleton | TypeImageTextSkeleton | TypeParagraphSkeleton | TypeProductSkeleton | TypeShopableImageSkeleton | TypeVideoSkeleton |
Component: GridTile
Parameter | Details |
---|---|
uid? | string |
content? | TypeClickableImageSkeleton | TypeImageSkeleton | TypeProductSkeleton | TypeShopableImageSkeleton | TypeVideoSkeleton |
headline? | string |
cta? | string |
ctaLink? | string |
Component: ImageText
Parameter | Details |
---|---|
uid? | string |
image? | TypeImageSkeleton[] |
topline? | string |
headline? | string |
text? | string |
cta? | string |
ctaLink? | string |
align? | 'center' | 'end' | 'start' |
justify? | 'center' | 'end' | 'start' |
Component: ProductSlider
Parameter | Details |
---|---|
uid? | string |
headline? | string |
ctaLabel? | string |
ctaUrl? | string |
productIds? |
References to SCAYLE products |
marginTop? | TypeMarginSkeleton |
Component: Banner
Parameter | Details |
---|---|
uid? | string |
isActive? | boolean |
type | 'hightlight' | 'info' | 'sale' |
body? | string |
countdownUntil? | string |
links? | TypeBannerLinkSkeleton[] |
ctaUrl? | string |
Component: Entry
Parameter | Details |
---|---|
color | string |
image | Asset |
label | string |
ctaUrl | string |
Footer
Component: Footer
Parameter | Details |
---|---|
uid? | string |
slug | string |
text? | Richtext |
alignRight? | boolean |
linkGroups? | TypeLinkGroupSkeleton[] |
textBottom? | string |
socialMedia? | TypeSocialMediaLinkSkeleton[] |
Component: LinkGroup
Parameter | Details |
---|---|
uid? | string |
title? | string |
links? | TypeLinkSkeleton[] |
Component: Link
Parameter | Details |
---|---|
uid? | string |
label | string |
ctaUrl | string |
openInNewTab? | boolean |
Listing Pages
Component: ListingPage
Parameter | Details |
---|---|
uid? | string |
teaserImage? | Asset |
teaserImageMobile? | Asset |
preListingContent? | EntrySkeletonType[] |
postListingContent? | EntrySkeletonType[] |
seo? | TypeSeoSkeleton |
Service Pages
Component: Accordion
Parameter | Details |
---|---|
uid? | string |
hasLinkList? | boolean |
entries? | TypeAccordionEntrySkeleton[] |
marginTop? | TypeMarginSkeleton |
Component: AccordionEntry
Parameter | Details |
---|---|
uid? | string |
title? | string |
linkTitle | string |
body? | Richtext |
Content Pages
Component: Content Page
Parameter | Details |
---|---|
uid? | string |
teaserImage? | Asset |
teaserImageMobile? | Asset |
headline? | string |
subline? | string |
content? |
|
| TypeCmsTextSkeleton
| TypeDoubleColumnSkeleton
| TypeGridSkeleton
| TypeImageSkeleton
| TypeImageSliderSkeleton
| TypeParagraphSkeleton
| TypeProductSliderSkeleton
| TypeSlideShowSkeleton
| TypeSocialMediaLinkSkeleton
| TypeVideoSkeleton>
| | seo?
| TypeSeoSkeleton
|
All Pages
Component: Video
Parameter | Details |
---|---|
uid? | string |
control_color? | string |
autoplay? | boolean |
has_controls? | boolean |
is_containered? | boolean |
video | Asset |
preview_desktop_image? | Asset |
preview_mobile_image? | Asset |
loop? | boolean |
tracking? | TypeTrackingSkeleton |
marginTop? | TypeMarginSkeleton |
Component: ClickableImage
Parameter | Details |
---|---|
uid? | string |
image? | TypeImageSkeleton[] |
ctaUrl? | string |
tracking? | TypeTrackingSkeleton |
marginTop? | TypeMarginSkeleton |
Component: Image
Parameter | Details |
---|---|
uid? | string |
desktopImage? | Asset |
mobileImage? | Asset |
tracking? | TypeTrackingSkeleton |
Component: Text
Parameter | Details |
---|---|
uid? | string |
body? | Richtext |
Component: DoubleColumn
Parameter | Details |
---|---|
uid? | string |
columnRight? | EntrySkeletonType[] |
columnLeft? | EntrySkeletonType[] |
marginTop? | TypeMarginSkeleton |
Component: Paragraph
Parameter | Details |
---|---|
uid? | string |
headline? | string |
cta? | string |
body? | Richtext |
subTitle? | string |
image? | Asset[] |
Component: settings - tracking
Parameter | Details |
---|---|
item_id? | string |
item_name? | string |
promotion_id? | string |
promotion_name? | string |
creative_name? | string |
creative_slot? | string |
location_id? | string |
index? | string |
Component: settings - margin
Parameter | Details |
---|---|
marginTop | '2xl' | 'lg' | 'md' | 'sm' | 'xl' | 'xs' |
Component: settings - seo
Parameter | Details |
---|---|
title | string |
description | string |
ogTitle | string |
ogDescription | string |
ogImage | string |
twitterTitle | string |
twitterDescription | string |
twitterImage | string |