CMS Integration
The Storefront SDK is in beta. Content in this section may be updated as the SDK evolves.
CMS integration works differently depending on which approach you use:
| Approach | CMS role |
|---|---|
| Pattern A (Accelerator) | The Accelerator owns routing. The CMS handles content pages via a catch-all route. This is what the adapter pattern below describes. |
| Pattern B (CMS-led) | The CMS owns all pages, URLs and routing. You import SDK Services and UI Components into your CMS's frontend framework. The adapter pattern is not needed because your CMS handles content directly. |
| Pattern C (SDK-only) | No CMS involvement. You handle content in your own code. |
The rest of this page describes how CMS integration works in the Accelerator (Pattern A). Strapi is the default CMS. Partners using a different CMS can write their own adapter.
The adapter pattern
The Accelerator uses a CMS adapter pattern so that page templates and CMS block components never depend on a specific CMS. Three packages make this work:
| Package | Purpose |
|---|---|
@propeller/cms-core | Unified TypeScript interfaces (CmsProvider, CmsPage, CmsBlock, CmsImage). Accelerator page templates and CMS block components depend on these types. |
@propeller/cms-strapi | Strapi adapter with normalizers that transform Strapi responses into the unified types. This is the default. |
Partners pick their CMS by changing a single file:
// lib/cms/index.ts
import { createStrapiProvider } from '@propeller/cms-strapi';
export const cmsProvider = createStrapiProvider({
apiUrl: '...',
apiToken: '...',
});
To switch to a different CMS, only this file changes. No components, routing config or templates need to change.
Writing a custom adapter
If your project uses a CMS other than Strapi, you implement the interfaces defined in @propeller/cms-core. Your adapter normalizes your CMS's response format into the unified types that the Accelerator's page templates and CMS block components expect.
CMS block components
CMS block components live in the Accelerator, not in the UI Components library. They are distinct from the SDK-only UI components described in Layer 2.
CMS block components receive data through the unified CmsPage and CmsBlock types. A HeroBanner block component does not know which CMS is behind the adapter. It receives a block object with fields like image, title and categoryId, and renders them.
This separation means you can evaluate or switch CMS platforms without rewriting your Accelerator's CMS block components.
Bridge blocks
Bridge blocks are the key pattern for combining CMS content with commerce data. A bridge block is a component that:
- Receives editorial data from the CMS (an image, a category ID, a text block)
- Fetches commerce data from the Propeller SDK (category name, product list, pricing)
- Renders both together
For example, an editor sets categoryId: 17 and uploads a banner image in the CMS. The bridge block component fetches the category name and slug from the Propeller API, then renders the banner image alongside the category title with a link to the category page.
Dynamic block rendering
CMS pages are built from blocks (called Dynamic Zones in Strapi). The Accelerator includes a DynamicBlockRenderer that maps each block type to a component:
| Block type | Component |
|---|---|
hero-banner | HeroBanner |
rich-text | RichText |
category-banner | CategoryBanner |
product-carousel | ProductCarousel |
When you create custom block types in your CMS, you add the mapping in components/cms/DynamicBlockRenderer.tsx.
Site-wide CMS data
The header, footer and navigation links are managed in the CMS under a global configuration (a "single type" in Strapi). The root layout.tsx calls getGlobal() on every request and makes the result available to all pages through a GlobalProvider.
When a CMS is connected, global data (logo, navigation, footer) is fetched for every page, including commerce pages. When no CMS is configured, getGlobal() returns null and the application renders without CMS data.
See also
- Routing for how CMS routes and commerce routes are resolved
- Accelerator for how the CMS layer fits into the Accelerator
- Choosing Your Approach for the three common partner architectures