Skip to main content

Building a CMS Integration Plugin

A CMS integration plugin allows you to automatically synchronize your Vendure product catalog with an external Content Management System.

This is done in a way that establishes Vendure as the source of truth for the ecommerce's data.

This guide demonstrates how to build a production-ready CMS integration plugin. The principles covered here are designed to be CMS-agnostic, however we do have working examples for various platforms.

Platfroms covered in the guide:

Working Example Repository

Info

This guide provides a high-level overview of building a CMS integration plugin. For complete implementations, refer to working examples repository

The code examples in this guide are simplified for educational purposes. The actual implementations contain additional features like error handling, retry logic, and performance optimizations.

Prerequisites

  • Node.js 20+ with npm package manager
  • An existing Vendure project created with the Vendure create command
  • An access key to a CMS platform that provides an API

Core Concepts

This plugin leverages several key Vendure concepts:

  • EventBus: Provides real-time notifications when entities are created, updated, or deleted.
  • Job Queues: Ensures that synchronization tasks are performed reliably and asynchronously, with retries on failure.
  • Plugin API: The foundation for extending Vendure with custom capabilities.

How It Works

The CMS integration follows a simple event-driven flow:

This ensures reliable, asynchronous synchronization with built-in retry capabilities.

Plugin Structure and Types

First, let's use the Vendure CLI to scaffold the basic plugin structure:

This command will create the basic plugin structure. Next, we'll generate the required services:

Now we start by defining the main plugin class, its services, and the configuration types.

Plugin Definition

The CmsPlugin class registers the necessary services (CmsSyncService, CmsSpecificService) and sets up any Admin API extensions.

src/plugins/cms/cms.plugin.ts

Configuration Types

The plugin's configuration options are defined in a types.ts file.

Create this file in your plugin directory to define the interfaces. These options will be passed to the plugin from your vendure-config.ts.

Note

This would be created for you automatically when you run the CLI command npx vendure add

src/plugins/cms/types.ts

Event-Driven Synchronization

The plugin uses Vendure's EventBus to capture changes in real-time.

In the onModuleInit lifecycle hook, we create job queues and subscribe to entity events.

Creating Job Queues and Subscribing to Events

You can also scaffold job queue handlers using the CLI:

This creates a productSyncQueue in the CmsSyncService. The service will be responsible for setting up the queues and processing the jobs. It will expose public methods to trigger new jobs.

src/plugins/cms/services/cms-sync.service.ts

Next, in the CmsPlugin, we subscribe to the EventBus and call the new service method to add a job to the queue whenever a relevant event occurs.

src/plugins/cms/cms.plugin.ts

Implementing the Sync Logic

The sync logic is split into two services: a generic service to fetch data, and a specific service to communicate with the CMS.

CmsSyncService orchestrates the synchronization logic. It acts as the bridge between Vendure's internal systems and your CMS platform, handling data fetching, relationship resolution, and error management.

Tip

Separating orchestration logic from CMS-specific API calls allows for better testability and maintainability. The sync service handles Vendure-specific operations while CMS services focus on API communication.

Core Responsibilities

The sync service handles several critical functions:

  • Entity Data Fetching: Retrieves complete entity data with necessary relations
  • Translation Management: Handles Vendure's multi-language support
  • Relationship Resolution: Manages complex entity relationships
  • Error Handling: Provides consistent error handling and logging

Service Structure and Dependencies

The service follows Vendure's dependency injection pattern and requires several core Vendure services:

src/plugins/cms/services/cms-sync.service.ts

Product Synchronization

Product sync demonstrates the complete workflow from job processing to CMS communication:

Ts

Relationship Handling

The service includes methods to resolve entity relationships. For example, finding collections that contain a specific variant:

Ts
Additional Entity Types

The service can also includes syncVariantToCms() and syncCollectionToCms() methods that follow the same pattern as the product sync shown above.

These implementations are omitted from this guide for brevity, but they handle their respective entity types with similar data fetching, relationship resolution, and error handling patterns.

The complete implementations can be found in the working example repositories.

This sync service provides the foundation for handling all Vendure-specific complexity while delegating CMS API communication to specialized services.

Platform specific setup

Working Example

The complete, production-ready Storyblok implementation can be found in the Storyblok integration example. Refer to it for a minimal working implementation.

Setting up Storyblok Space

1. Create a Storyblok Account and Space

  1. Sign up at storyblok.com if you don't have an account
  2. Create a new Space (equivalent to a project in Storyblok)
  3. Choose a suitable plan based on your needs

2. Get Your API Credentials

  1. Navigate to Settings → Access Tokens in your Storyblok space
  2. Create a new Management API Token with write permissions
  3. Note down your Space ID (found in Settings → General)

3. Configure Environment Variables

Add these variables to your .env file:

Env

The Storyblok Service

StoryblokService handles all Storyblok-specific operations including API communication, content type management, and data transformation. Key features include:

  • Content Type Management: Automatically creates Vendure-specific content types (components) in Storyblok
  • Story Management: CRUD operations for stories representing products, variants, and collections
  • Relationship Handling: Manages references between products, variants, and collections

Basic Service Structure

The service follows Vendure's standard dependency injection pattern and implements OnApplicationBootstrap to ensure Storyblok is properly configured before handling sync operations.

src/plugins/cms/services/storyblok.service.ts

Making API Requests

All Storyblok API communication is centralized through a single method that handles authentication, error handling, and response parsing. This approach ensures consistent behavior across all operations.

Ts

Data Transformation

Transformation methods convert Vendure entities into the format expected by Storyblok's API. The content object structure must match the component schema defined in Storyblok.

Ts

Relationship Handling

One of the most important aspects of CMS integration is maintaining relationships between entities. Products have variants, variants belong to collections, and these relationships need to be reflected in the CMS. Storyblok uses story UUIDs to create references between content pieces.

  • Finding Related Entities

First, we need methods to query the Vendure database for related entities:

Ts
  • Batch Story Lookups

We can also use batch lookups to find multiple stories at once:

Ts
  • Building Relationships

Finally, we combine database queries with CMS lookups to build relationships:

Ts

CRUD Operations

These methods handle the basic Create, Read, Update, and Delete operations for stories in Storyblok. They follow REST API conventions and leverage the centralized request method for consistent behavior.

Ts

Final Plugin Configuration

src/vendure-config.ts

This setup provides a complete Storyblok CMS integration that automatically creates the necessary content types and syncs your Vendure catalog with structured content in Storyblok.

The complete implementations can be found in the working example repositories.

Admin API Integration

To allow for manual synchronization through graphQL mutations, we can extend the Admin API with new mutations. Let's use the CLI to generate the API extensions:

Extending the GraphQL API

src/plugins/cms/api/api-extensions.ts

Implementing the Resolver

The resolver for these mutations re-uses the existing CmsSyncService to add a job to the queue.

src/plugins/cms/api/cms-sync-admin.resolver.ts

Final Configuration

Finally, add the plugin to your vendure-config.ts file with the appropriate configuration for your chosen CMS platform.

src/vendure-config.ts

Refer to the platform-specific configuration examples in the tabs above for the exact environment variables and options needed for your chosen CMS.

For complete, production-ready implementations, see the working examples:

Was this chapter helpful?
Report Issue
Edited Feb 12, 2026·Edit this page