Routing
The Storefront SDK is in beta. Content in this section may be updated as the SDK evolves.
This page describes routing in the Accelerator (Pattern A: Commerce-led). In a CMS-led architecture (Pattern B), the CMS owns all routing and the patterns below do not apply.
The Accelerator splits routing between file-system routes (commerce pages) and the CMS (content pages). A single route config file controls URL patterns for both.
Route config file
The route config is a single project-wide file that defines URL patterns and CMS settings. Every component that needs URL information receives this config as a property.
// lib/routing/routes.config.ts
The config contains:
baseCategoryId— the root category ID for your Propeller environment- Commerce patterns for product, category and other commerce URLs
- CMS patterns for content pages served by the headless CMS
Commerce patterns
Commerce patterns define the public URL structure for commerce pages. Each pattern has three fields:
| Field | Description |
|---|---|
pattern | The public URL (e.g. /product/:id/:slug) |
internal | The corresponding app/ folder path in Next.js |
source | Always 'commerce' for commerce routes |
Partners customize the pattern to match their URL strategy. For example, a Dutch storefront might change /category/:id/:slug to /categorie/:id/:slug. The next.config.ts reads the route config and auto-generates Next.js rewrites so the custom URL internally renders the correct page.
This means you change URLs in one place and all components that generate links follow the new pattern.
CMS patterns
CMS patterns define which URL groups are served by the headless CMS. Each pattern has:
| Field | Description |
|---|---|
pattern | URL pattern with wildcards (e.g. /blog/**) |
template | The page template to use (e.g. blog-post) |
revalidate | Cache revalidation time in seconds |
A /** wildcard acts as a fallback. This means every page created in the CMS is automatically available on the frontend without any config change. Partners only add specific patterns when they need a different template or caching strategy for a group of pages.
How routes are resolved
Next.js matches routes from most specific to least specific:
-
Hardcoded commerce routes are matched first. Pages like
/login,/cart,/product/[productId]/[slug]and/category/[id]/[slug]are standard Next.js App Router routes with their ownpage.tsxfiles. -
CMS catch-all route handles everything else. The file
app/(cms)/[...slug]/page.tsxis a catch-all inside a(cms)route group. The(cms)prefix is invisible in the URL.
When a request arrives for a URL like /about-us:
- No hardcoded route matches
/about-us - The CMS catch-all receives the request
- The slug is used to query the CMS for a page matching
about-us - If the CMS has a page, it is rendered using the
DynamicBlockRenderer - If no page is found, a 404 is returned
Commerce routes always take priority over CMS pages. A CMS page cannot override /cart or /login.
URL builder utilities
The SDK provides URL builder functions that generate URLs based on the route config:
categoryUrl()generates a category URL from a category objectproductUrl()generates a product URL from a product object
These functions read the patterns from the route config, so changing a URL pattern in the config automatically updates all generated links across the application.
Caching
CMS content caching is configured per route pattern using the revalidate field:
- Development:
cache: 'no-store'(always fresh data) - Production: ISR (Incremental Static Regeneration) with a configurable revalidation interval
The CMS also supports on-demand revalidation through webhooks. A /api/revalidate endpoint receives webhook calls from the CMS and invalidates the cached page. This endpoint uses cmsProvider.verifyWebhook() for security, making it CMS-agnostic.
Static generation
At build time, generateStaticParams() fetches all page slugs from the CMS and pre-renders them as static HTML. The home page is excluded from this list because it is handled by app/page.tsx.
What partners configure
| File | What | How often |
|---|---|---|
lib/routing/routes.config.ts | URL patterns, templates, caching | Once at setup, rarely changed |
lib/cms/index.ts | CMS provider choice | Once at setup |
.env | API URLs and tokens | Once at setup |
components/cms/DynamicBlockRenderer.tsx | Custom block type mappings | When adding custom blocks |
components/cms/templates/ | Custom page layouts | When adding new layouts |
See also
- CMS integration for the adapter pattern and bridge blocks
- Categories and navigation for the underlying category data model