docs
  1. Integrations
  2. Cms
  3. Contentful

Contentful

Overview

Contentful is a highly scalable, API-first headless CMS platform designed for large volumes of complex, structured content. The SCAYLE Storefront Application includes a comprehensive, production-ready integration that leverages Contentful's powerful API and content modeling capabilities.

The integration manages API complexity, allowing your team to focus on building and deploying stunning content experiences. You get structured content with strong typing, flexible content modeling, and high-performance delivery.

Key Features

  • Content Model Stability: Structured content types with precise developer control and strong
  • Inspection Mode: Click-to-edit functionality for direct content editor integration.typing.
  • Live Preview: Real-time content editing with instant preview updates in the Contentful editor.
  • Component Flexibility: Pre-built component library with automatic component resolution and custom component support.
  • Locale Support: Multi-language content with configurable fallback chains and automatic locale detection.
  • Type Safety: Automatic TypeScript type generation from Contentful content models.

Getting Started

Prerequisites

Before setting up Contentful, ensure you have the following ready:

  • Contentful account: Sign up at contentful.com.
  • Contentful space: Create a new space for your new Storefront Application project.
  • Access tokens:

Setup Your Contentful Storefront

The Contentful integration is included with the Storefront Application. To enable and configure it:

Step 1: Run Setup Command

Run the SCAYLE Storefront CLI setup command, passing contentful with the --provider flag:

This command prompts you to:

  • Select a CMS provider (choose "contentful").
  • Provide your Contentful space ID.
  • Provide a Delivery API access token.
  • Provide a Preview API access token.
  • Provide a Management API access token.
  • Specify whether to import the content model.

Importing the content model is only intended for empty CMS spaces. Running it on spaces with existing content may cause issues.

Step 2: Review Configuration

After setup, your nuxt.config.ts will include:

The following environment variables are updated in your local .env file:

  • CMS_PROVIDER (required during build-time)
  • NUXT_PUBLIC_CMS_SPACE (required during runtime)
  • NUXT_PUBLIC_CMS_ACCESS_TOKEN (required during runtime)
  • NUXT_PUBLIC_CMS_PREVIEW_ACCESS_TOKEN (optional during runtime)
  • CONTENTFUL_MANAGEMENT_TOKEN (required for cli commands)

Step 3: Environment Configuration & Deployment

The Contentful integration leverages Nuxt's RuntimeConfig, which provides flexibility for different deployment environments.

Runtime vs Build-Time Configuration

Unlike traditional build-time configuration, environment variables can be set at runtime. This means:

  • During development: Set variables in your .env file.
  • During deployment: Update environment variables on your hosting platform without rebuilding.
  • Different environments: Use the same build for development, staging, and production with different variables.

Environment Variables Reference

All Contentful configuration can be set via environment variables:

Production Deployment Checklist

  • Use Delivery API token in production (not Preview token)
  • Optionally disable Live Preview in production (_editorMode not in URL)
  • Use Preview token only in development/staging environments
  • Ensure all required environment variables are configured on your hosting platform
  • Test content loading in your production environment before going live

Architecture & Integration

Shop Runtime Integration

The runtime integration between Contentful and the Storefront Application uses the contentful, @contentful/rich-text-html-renderer and @contentful/live-preview packages.

The integration additionally relies on the @nuxt/image module (see the Nuxt Image module documentation) to handle images used with Contentful components.

How It Works

Contentful uses a content-type-based architecture where content is built from flexible, reusable content blocks. Each Contentful content type maps to a Vue component in your application, enabling a seamless bridge between your CMS and Storefront.

Content Type Mapping Pattern:

  • Contentful content type TextComponent → Vue component TextComponent.vue
  • Contentful content type ImageComponent → Vue component ImageComponent.vue
  • Contentful content type SectionComponent → Vue component SectionComponent.vue
  • Contentful content type ProductListingPageComponent → Vue component ProductListingPageComponent.vue

Content Organization Architecture

To connect your application with Contentful content, set up the correct content structure in your CMS.

Create the Homepage

Your homepage content must be created with a specific slug to be automatically picked up by the application's routing:

  • Contentful Slug: homepage

Create Locales

Organize your content by locale in Contentful:

  1. Go to "Settings → Locales".
  2. Create locales matching your shop codes (e.g., de-DE, en-US, de-AT).
  3. Set appropriate fallback chains for locale resolution.

Example Locale Setup:

  • de-DE (German) - Fallback to en-US
  • de-AT (Austrian) - Fallback to de-DEen-US
  • de-CH (Swiss) - Fallback to de-DEen-US
  • en-US (English) - Default fallback

Content Fetching Flow

When a user visits your storefront, the integration follows this flow:

  1. Route resolves: User navigates to a URL.
  2. Query construction: The integration builds a Contentful query with the slug and locale.
  3. Locale detection: Current shop locale is automatically included.
  4. API request: Content is fetched from Contentful (Delivery or Preview API).
  5. Component mapping: Contentful entries are mapped to Vue components.
  6. Rendering: Vue components render the content with proper styling.

Locale & Fallback Strategy

Contentful provides powerful locale fallback capabilities. The integration uses a hybrid approach for optimal performance:

Configure fallback locales directly in your Contentful space for server-side handling:

  1. Go to "Settings" → "Locales".
  2. Set fallback chains for each locale.
  3. Example: de-CHde-DEen-US.

Benefits:

  • Single API request (no retry needed).
  • Granular control over fallback chains.
  • Content team configures logic in the CMS.
  • Handles partial translations elegantly.

Secondary: Application-Level Fallback (Safety Net)

If a locale is unconfigured in Contentful, the integration provides automatic fallback:

  1. Attempt to fetch content with the shop's configured locale.
  2. If that fails with a BadRequest error, automatically retry without specifying a locale.
  3. Log a warning recommending proper configuration in Contentful.

When this applies:

  • Launching in a new market before the locale is configured.
  • Testing with locale combinations not yet set up.
  • Edge cases during development.

Live Preview Integration

Live Preview enables you to see changes in real-time as you edit content in Contentful:

  1. Editor detection: The integration detects the _editorMode query parameter.
  2. Preview API activation: Client switches to Preview API with preview access token.
  3. Draft content loading: Draft versions are loaded instead of published versions.
  4. Live updates: Changes in Contentful appear instantly in the preview.
  5. Deep reactivity: Component updates trigger Vue re-renders automatically.
Contentgul Preview

Contentful Preview

Configure Preview Access

To display unpublished changes on initial load in the Contentful editor, your access token must have the Preview API permission. If your token doesn't have preview access, unpublished changes appear only after publishing in the editor.

Configure Preview URLs in Contentful

In your Contentful space, configure preview URLs for each content type:

  1. Go to "Settings" → "Content preview".
  2. Add preview URL for each content type (e.g., http://localhost:3000 for local development).
  3. Include the _editorMode query parameter with the entry's updated timestamp.

Example preview URLs:

Locale to Path Mapping:

This feature requires a Contentful Premium plan. For details, see Contentful's custom preview tokens documentation.

To map content locales to their respective shops, configure custom preview tokens in your Contentful settings. Custom preview tokens allow you to create locale-specific URL strings and parameters that resolve differently for each locale during preview.

To set up custom preview tokens:

  1. Go to "Settings → Content preview".
  2. Scroll to "Custom preview tokens" at the bottom.
  3. Click "Copy template to clipboard" to get the JSON template.
  4. Adjust the tokens to map your locales to shop paths:\

This configuration allows preview URLs like https://your-domain.com/{localeToPath[{locale}]}/content/{entry.fields.slug}?_editorMode={entry.sys.updatedAt} to automatically resolve to the correct shop path based on the content's locale.

Enable Inspection Mode for Live Preview

Use data attributes on component root elements to enable click-to-edit functionality:

  • data-contentful-entry-id: Identifies the entry being edited
  • data-contentful-field-id: Identifies the specific field being edited

These attributes enable content editors to click directly on content in the preview to edit it.

Test Live Preview

  1. Create draft content in Contentful.
  2. Set up preview URL with _editorMode parameter.
  3. Click "Open preview" in Contentful.
  4. Verify the preview loads correctly.
  5. Make changes in Contentful and verify they appear instantly.

Embedding CMS Content in Existing Pages

You can enrich existing Storefront Application pages with CMS-managed sections without converting the entire page to CMS. The Product Listing Page (PLP) demonstrates this pattern:

This pattern lets you add CMS-controlled blocks to any page region while keeping core page logic in your application.

Available Components

The integration provides pre-built components organized by function. These components serve as building blocks for your content. You can explore all components in our UI Component Overview.

Core Content Primitives

ComponentDescription
TextComponentText content with flexible heading levels (h1-h4) and paragraphs.
LinkComponentNavigable text and image links with proper URL resolution.
ImageComponentOptimized images with responsive sizing and aspect ratio.
VideoComponentEmbed videos with customizable playback controls.

Interactive & Basic Content Blocks

ComponentDescription
AccordionComponentCollapsible accordion sections.
AccordionItemComponentIndividual accordion items with expand/collapse functionality.
ButtonComponentAction buttons with configurable styling and link destinations.

Layout & Structural

ComponentDescription
PageComponentTop-level page container for full-page content.
ProductListingPageComponentSpecialized component for category page content.
SectionComponentContent container with background image/color support.
GridComponentMulti-column layout system for content organization.
DividerComponentVisual spacing and divider elements.

Rich Content

ComponentDescription
RichTextComponentContentful rich text with proper formatting and link resolution.

E-Commerce Specific

ComponentDescription
SliderComponentCarousel for multiple content items.
ProductSliderComponentProduct carousel with selectable products.
RecentlyViewedProductsComponentRecently viewed products.
SmartSortingProductsSliderComponentConfigurable product slider that accepts a Smart Sorting Key and additional parameters.

Guidelines: Content

Using Base Components

The included pre-built components provide all the building blocks needed to create common e-commerce content patterns. Compose flexible sections that adapt to your brand and merchandising needs.

Hero Banner

Combine these components to create an impactful hero banner:

  1. Use SectionComponent with a background image.
  2. Add TextComponent for the headline and description.
  3. Include one or more ButtonComponent instances for calls-to-action.
  4. Use DividerComponent for vertical spacing.

Structure

Category Teasers / Cards

Create a card grid layout:

  1. Use GridComponent with four columns on desktop, two on mobile.
  2. Inside each column, add SectionComponent with a background image.
  3. Include ButtonComponent to link to the category page.

Structure

Promotional Slider

Implement a carousel pattern:

  1. Use SliderComponent as the container.
  2. For each slide use a SectionComponent as container.
  3. Add TextComponent for each slide title.
  4. Add DividerComponent as separator.
  5. Include ButtonComponent to drive users to listings or campaigns.

Structure

Split Image & Text Section

Create a side-by-side layout:

  1. Use GridComponent with two columns on desktop, one on mobile.
  2. First column: SectionComponent with background image.
  3. Second column: TextComponent for headline/description and ButtonComponent for CTA.

Structure

By combining these base primitives, you can build visually appealing, commerce-relevant sections without custom code.

Creating Content for PLP

The Product Listing Page (PLP) is a main discovery point in the user journey. Our specialized component allows you to seamlessly inject custom, commerce-relevant content before and after your product stream.

Follow these steps to set up content for a specific category:

Congratulations! Your customized PLP content is now ready to go live.

Guidelines: Development

Customizing Existing Components

You can customize existing components by modifying their Vue implementations to match your design system and requirements.

How Component Customization Works

All Contentful components are rendered through the ContentfulComponent registry. To customize a component:

  1. Locate the component in modules/cms/providers/contentful/components/ .
  2. Modify the Vue component to match your design system.
  3. Test in Live Preview to verify your changes.

Available Components to Customize

The integration provides a comprehensive set of pre-built components that can be customized:

  • TextComponent.vue - Customize text rendering and styling
  • ImageComponent.vue - Customize image display and responsiveness
  • ButtonComponent.vue - Customize button appearance and interactions
  • SectionComponent.vue - Customize layout and spacing
  • GridComponent.vue - Customize grid columns and gaps
  • LinkComponent.vue - Customize link styling and behavior
  • ... and all other available components.

Each component is registered in the ContentfulComponent (see the "Nested Components" section for details on how this registry works).

To customize any component, navigate to modules/cms/providers/contentful/components/ and modify the Vue implementation to match your brand and design requirements.

Nested Components

Contentful content types can reference other content types, creating nested component hierarchies. The ContentfulComponent serves as the central registry that maps all Contentful content types to their corresponding Vue components.

How ContentfulComponent Works:

The ContentfulComponent is a dynamic component dispatcher that:

  1. Receives a Contentful entry (content element) as a prop
  2. Examines the entry's content type
  3. Renders the appropriate Vue component based on the content type
  4. Passes the entry data to the mapped component

This allows you to build deeply nested content structures where any content type can contain references to other content types, and they'll all render correctly without needing to know about each other.

Example - Nested Content:

Components can contain other components via reference fields:

The ContentfulComponent Registry:

Under the hood, ContentfulComponent.vue contains a series of conditional branches that determine which Vue component to render:

Benefits of This Pattern:

  • Flexibility: Build complex content hierarchies with any combination of components.
  • Reusability: Components don't need to know about each other, just about ContentfulComponent .
  • Maintainability: Add new components to one central place (the registry).
  • Type Safety: Type guards (e.g., isTypeTextComponent) ensure correct component rendering.
  • Fallback Handling: Unknown component types display a helpful message instead of breaking.

Building New Components

Creating new Contentful components allows you to extend the pre-built library with custom functionality.

Step 1: Define Content Type in Contentful

  1. Go to your Contentful space → "Content model".
  2. Click "Add content type".
  3. Define the content structure with appropriate fields (text, images, references, etc.).
  4. Publish the content type schema.

Step 2: Generate TypeScript Types

After defining your content type, generate types by running the cms:sync command from your Storefront Application root directory:

This command:

  1. Exports content schema from your Contentful space.
  2. Generates TypeScript types automatically.
  3. Organizes types in modules/cms/providers/contentful/types/gen/ .

What Gets Generated

The cms:sync command generates:

  • Content type interfaces: Full TypeScript definitions for all Contentful content types.
  • Type files: Organized in modules/cms/providers/contentful/types/gen/ .
  • Type guards: Ready-to-use type checking utilities (e.g., isTypeMyBannerComponent).

Generated Type Example

After running pnpm cms:sync, your component types are automatically available:

Import Generated Types

Use the auto-generated types in your Vue components:

Never manually edit files in modules/cms/providers/contentful/types/gen/. These are auto-generated and will be overwritten when you run pnpm cms:sync again.

Step 3: Create Vue Component

Create a corresponding Vue component in your application. Components receive a contentElement prop containing the Contentful entry data:

Step 4: Register Component

Register the component in ContentfulComponent.vue to make it renderable:

Best Practices

Content Organization

  • Use consistent naming: Follow a clear naming convention for content types and fields.
  • Organize with references: Use reference fields to create reusable content blocks.
  • Leverage validation: Use Contentful's field validations to ensure content quality.
  • Document content models: Add descriptions to content types and fields for team clarity.

Translation Workflow

  • Configure fallback locales: Set up fallback chains in Contentful for optimal performance.
  • Create default locale first: Start with one locale as the source of truth.
  • Use Contentful's translation features: Leverage built-in translation workflows.
  • Review process: Implement a review process for translated content before publishing.
  • Test across locales: Verify content displays correctly in all locales.

Performance

  • Use lazy loading: Enable lazy: true for below-the-fold content.
  • Optimized images: Use the existing image component provided.
  • Leverage caching: Use unique cache keys for proper deduplication.
  • Monitor payload size: Keep content payloads small by selecting only needed fields.
  • Use Contentful's native fallback: Configure fallback locales in Contentful for single API call.

SEO Considerations

  • Unique meta tags: Ensure each page has unique meta titles and descriptions.
  • Structured data: Add structured data fields to content types when appropriate.
  • Canonical URLs: Set canonical URLs appropriately for each page.
  • Sitemap: Generate sitemaps that include CMS-managed pages.
  • Hreflang tags: Implement hreflang tags for multilingual SEO.

Development Workflow

  • Use Live Preview: Enable Live Preview for content editors during development.
  • Sync types regularly: Run pnpm cms:sync after content model changes.
  • Test with draft content: Verify draft content displays correctly before publishing.
  • Handle errors gracefully: Implement proper error boundaries and fallbacks.

Troubleshooting

Content Not Loading

Problem

Content exists in Contentful but doesn't appear in the application.

Possible causes:

  • Configuration is incorrect or missing
  • Content is not published in Contentful
  • Slug in Contentful doesn't match the query
  • Content doesn't exist in the requested locale

Solutions

  1. Verify NUXT_PUBLIC_CMS_SPACE and NUXT_PUBLIC_CMS_ACCESS_TOKEN are set correctly
  2. Ensure content is published in Contentful
  3. Check that the slug in Contentful matches the query exactly
  4. Verify content exists in the requested locale or configure fallback locales
  5. Check browser console and server logs for error messages

Prevention: Use consistent slug naming conventions and test content in all locales before publishing.

Debugging

Type Errors

Problem

TypeScript errors when using generated types.

Possible causes:

  • Generated types are outdated.
  • Importing from incorrect path.
  • Contentful content model doesn't match expected structure.

Solutions

  1. Run pnpm cms:sync to regenerate types.
  2. Verify you're importing from ~/modules/cms/providers/contentful/types .
  3. Ensure Contentful content model matches expected structure.
  4. Clear TypeScript cache and restart IDE.

Prevention: Run pnpm cms:sync after every content model change in Contentful.

Live Preview Not Working

Problem

Live Preview doesn't load or shows errors.

Possible causes:

  • Preview access token is missing or incorrect
  • _editorMode query parameter is missing
  • Preview token doesn't have correct permissions
  • Content is not in draft state

Solutions

  1. Verify NUXT_PUBLIC_CMS_PREVIEW_ACCESS_TOKEN is set correctly.
  2. Check that _editorMode is in the preview URL.
  3. Verify preview token has correct permissions in Contentful.
  4. Ensure content is in draft state (not published).
  5. Check application logs for warnings.

Prevention: Test Live Preview setup in development before deploying to production.

Debugging:

Locale Issues

Problem

Wrong locale content is displayed or locale errors occur.

Possible causes:

  • Fallback locales are not configured in Contentful.
  • Shop locale codes don't match Contentful locale codes.
  • Locale is not configured in Contentful space.

Solutions

  1. Configure fallback locales in Contentful space settings.
  2. Ensure shop locale codes match Contentful locale codes exactly.
  3. Verify all required locales are configured in Contentful.
  4. Check application logs for locale-related warnings.

Prevention: Configure all required locales in Contentful before launching in new markets.

Debugging: