SfSkills Domains Docs GitHub

Home / architect / headless-commerce-architecture

headless-commerce-architecture

Use this skill when designing or evaluating a headless B2C Commerce storefront architecture — covering the Composable Storefront (PWA Kit on Managed Runtime), SCAPI-first API design, frontend framework selection, latency budgets, and caching strategy. NOT for standard SFRA storefronts, Experience Cloud headless CMS delivery, B2B Commerce architecture, or SCAPI implementation-level coding (use apex/headless-commerce-api for that).

Open the skill folder on GitHub


Headless Commerce Architecture

Use this skill when making or reviewing architecture decisions for a headless B2C Commerce Cloud storefront. It covers the canonical Composable Storefront stack (PWA Kit on Managed Runtime consuming SCAPI), frontend framework selection, SCAPI latency constraints, web-tier caching design, and the SLAS auth model that governs all Shopper API access. This skill does not cover SCAPI implementation-level coding — for that, use apex/headless-commerce-api.


Before Starting

Gather this context before working on anything in this domain:


Core Concepts

The Canonical Headless Stack: Composable Storefront on Managed Runtime

The canonical Salesforce headless B2C Commerce architecture consists of three tiers:

  1. PWA Kit (Composable Storefront) — the React-based frontend framework published and maintained by Salesforce. It provides the application shell, routing, server-side rendering (SSR) via React SSR, and a pre-built component library for common commerce pages (PDP, PLP, cart, checkout). Teams extend or replace components as needed. PWA Kit is the only officially supported way to deploy a headless storefront on Managed Runtime.
  2. Managed Runtime (MRT) — Salesforce's cloud hosting service for PWA Kit deployments. MRT handles serverless function execution (for SSR), a multi-region CDN, automated deployment pipelines via the Retail React App CLI, and runtime environment variable management. Web-tier caching of server-rendered responses occurs at the MRT/CDN layer.
  3. Salesforce Commerce API (SCAPI) — the exclusive backend API consumed by the frontend. SCAPI is organized into Shopper APIs (browse, basket, checkout, orders, customers) and Admin APIs (catalog management, inventory, pricing). The frontend exclusively calls Shopper APIs. Admin API calls originate from back-office tooling, not from storefront code.

Any component substituted into this stack (custom React build tool, self-hosted Node.js, third-party CDN) carries corresponding operational responsibility. The canonical stack is the lowest-risk path for teams new to Composable Storefront.

SCAPI Latency Constraints and the 10-Second Shopper API Timeout

SCAPI enforces a hard 10-second timeout on Shopper API requests. If a Shopper API call does not complete within 10 seconds, SCAPI returns HTTP 504. This is not a configurable limit — it is platform-enforced for all tenants.

This constraint has direct architectural implications:

Web-Tier Caching: TTL Caps and Cache-Key Design

The MRT CDN layer caches server-rendered responses. Web-tier cache TTLs for SCAPI-backed responses are capped at 86400 seconds (24 hours) — this is the platform maximum. TTLs above this value are silently clamped to 86400.

Cache-key design is a first-class architectural decision because:

Personalized content (promotions for a specific shopper, saved addresses, order history) must never be cached at the web tier. Personalized data is fetched client-side after the page shell is served from cache.

SLAS Authentication Architecture

The Shopper Login and API Access Service (SLAS) is the OAuth2 authorization server for all SCAPI Shopper API access. SLAS is architecturally distinct from Salesforce Identity (connected apps, OAuth flows on the Salesforce org). It is a dedicated service within the Commerce Cloud infrastructure.

SLAS issues short-lived JWT access tokens (default 30-minute expiry) and long-lived refresh tokens. All Shopper API requests require a valid SLAS JWT in the Authorization: Bearer header. There are no sessions, no cookies, and no OCAPI-style hook invocations in a SCAPI architecture.

The three session types and their architectural implications:

Session TypeGrant FlowStorefront Impact
Guest shopperclient_credentials + PKCERequired for all anonymous browsing — even product catalog calls require a token
Registered shopperAuthorization code + PKCEToken bound to customer identity; basket data is shopper-specific
Agent on behalf of shopperSLAS agent grantOnly needed for service rep console use cases; not for standard storefront

A critical architectural constraint: guest basket IDs are bound to the guest token's subject claim. When a shopper logs in, their cart cannot be accessed with the registered shopper token until a basket merge API call transfers the contents. This merge step must be designed into the cart and login flow.


Common Patterns

Pattern: Cache-First Page Architecture with Client-Side Personalization

When to use: Any product page (PDP, PLP, search results, category page) that serves the same content to all shoppers of the same locale and currency.

How it works:

  1. Server-side render the product page shell using SCAPI product/search data. Set a web-tier TTL appropriate to catalog update frequency (typically 300–3600 seconds for most product pages; lower for promotions with near-term expiry).
  2. Design the cache key to include site ID, locale, currency, and the content-specific identifier (product ID, search query, category ID). Exclude all session or user data from the cache key.
  3. Serve the cached shell immediately. The page is complete and indexable without JavaScript — this is critical for SEO.
  4. On the client side, after hydration, fetch personalized data (promotions for the current shopper, basket state, wishlist) from SCAPI using the SLAS JWT stored in memory. Inject personalized content into the already-rendered shell.

Why not the alternative: Full server-side assembly with personalization (including shopper-specific promotions in the SSR render) makes the page uncacheable at the web tier. Every page request becomes a live SCAPI call, and the 10-second timeout risk applies to all traffic at all times — including peak load.

Pattern: SCAPI Parallel Fetch with Latency Budget Enforcement

When to use: A page requires data from multiple SCAPI endpoints (e.g., product detail + product recommendations + active promotions) and the data can be fetched independently.

How it works:

  1. Identify which SCAPI endpoints are required for the server-side-rendered (above-the-fold) content vs. which can be deferred to client-side hydration.
  2. Issue SSR-required calls in parallel using Promise.all. Set a per-call timeout (recommended: 4 seconds for individual calls, 7 seconds for the parallel group) so the page can render with partial data rather than timing out entirely.
  3. On timeout or error, render the page with graceful degradation (e.g., no recommendations shown, promotions omitted) rather than returning a 500 or blank page.
  4. Defer non-critical SCAPI calls (reviews, cross-sell recommendations, personalized content) to client-side hydration so they do not contribute to the SSR latency budget.

Why not the alternative: Sequential SCAPI calls for a 4-endpoint page will typically consume 2–6 seconds of the 10-second budget on network alone, leaving no margin for SCAPI processing time or temporary load-shedding events.

Pattern: Storefront Stack Selection Decision (SFRA vs. Composable Storefront)

When to use: A new Commerce Cloud implementation or a storefront migration where the team must choose between SFRA and Composable Storefront.

Decision framework:

FactorComposable Storefront (PWA Kit)SFRA
Frontend team skillsStrong React/Next.js experienceSalesforce ISML/server-side templating experience
Customization depthFull UI/UX control; any React componentConstrained by ISML templates; plugin architecture
SEO requirementsSSR included; full control over markupSSR included via Business Manager sandbox
Third-party integrationsClean API boundary; any NPM packageIntegration via SFRA cartridge system
Infrastructure ownershipManaged Runtime (Salesforce-managed) or self-hostedBusiness Manager sandbox (Salesforce-managed)
Maintenance trajectoryActive investment from SalesforceMaintenance mode; no new feature investment from Salesforce

Composable Storefront is the strategic path for new implementations. SFRA remains the practical choice for teams with existing ISML investment or those who cannot staff React frontend engineers.


Decision Guidance

SituationRecommended ApproachReason
New B2C Commerce storefront, React team availableComposable Storefront (PWA Kit) on Managed Runtime, SCAPIStrategic platform direction; MRT reduces operational burden
New B2C Commerce storefront, no React expertiseSFRA with plan to migrate when team capability buildsSFRA is stable; a headless migration with under-skilled team increases risk
Migrating from SFRA to Composable StorefrontPhased migration: Composable Storefront for new categories first, SFRA for existing until parityFull-cutover migrations introduce high risk; phased reduces blast radius
Headless with custom design system (not Retail React App)Use PWA Kit as the SSR and routing layer; replace component library with customPWA Kit's MRT integration is the value; the component library is replaceable
Heavy third-party integrations (search, CMS, reviews)Wire integrations client-side or via server-side proxy on PWA KitSCAPI is not a middleware bus; third-party APIs should not be chained through SCAPI
High-traffic peak events (Black Friday, flash sales)Cache-first architecture with web-tier TTLs; personalization client-side onlyEliminates SCAPI calls for catalog pages under load; critical for surviving 10-second timeout risk
Personalized promotions on product pagesFetch promotions client-side after hydration; never include in SSR cache keyPersonalized content in SSR makes the page uncacheable; negates web-tier cache entirely
Custom frontend framework (Angular, Vue, non-React)Call SCAPI REST directly; do not use PWA Kit or Commerce SDK ReactPWA Kit and Commerce SDK React are React-specific; non-React stacks must implement SLAS PKCE manually

Step-by-step instructions for an AI agent or practitioner working on this task:

  1. Confirm the platform scope — Verify this is a B2C Commerce Cloud headless architecture decision, not Experience Cloud CMS, B2B Commerce, or SFRA configuration. Collect: Commerce Cloud org type, SCAPI enablement status, existing storefront technology (if any), and business requirements driving the headless decision.
  2. Select the storefront stack — Use the SFRA vs. Composable Storefront decision framework. If Composable Storefront is selected, confirm Managed Runtime is the hosting target unless specific data residency or infrastructure requirements mandate self-hosting. Document the stack decision and rationale in an architecture decision record.
  3. Design the SLAS authentication model — Identify which shopper session types the storefront requires (guest, registered, agent). Document the token acquisition flow for each type, token storage strategy (access token in memory, refresh token in httpOnly cookie), and the basket merge flow for guest-to-registered transitions.
  4. Define the SCAPI endpoint map and latency budget — List all SCAPI endpoints the storefront will call per page type (PDP, PLP, cart, checkout). Classify each call as SSR-required (must complete before HTML is sent) or client-side (can be deferred post-hydration). Verify the SSR-required call group fits within a 7-second parallel budget, leaving margin below the hard 10-second SCAPI timeout.
  5. Design the caching architecture — For each page type, specify: (a) web-tier TTL in seconds (cap at 86400); (b) cache-key components (at minimum: site ID, locale, currency, content identifier); (c) which content is personalized and must be fetched client-side after hydration. Confirm no session or user-specific data is included in web-tier cache keys.
  6. Validate against Well-Architected pillars — Check Performance (latency budget, cache-hit ratio targets), Security (SLAS token storage, PKCE enforcement, no secrets in frontend bundles), and Adaptability (integration points, component replaceability, migration path from SFRA if applicable).
  7. Produce and review the architecture deliverables — Deliver: stack decision record, SLAS auth model document, SCAPI endpoint map with latency budget, cache-key design table, and any open risk items. Review with the Commerce Cloud technical lead before development begins.

Review Checklist

Run through these before marking architecture work in this area complete:


Salesforce-Specific Gotchas

Non-obvious platform behaviors that cause real production problems:

  1. SCAPI Hard 10-Second Shopper API Timeout (HTTP 504) — SCAPI enforces a non-configurable 10-second timeout on all Shopper API requests. Any SSR path that chains SCAPI calls sequentially or waits on slow upstream enrichment steps will return HTTP 504 to the browser, rendering the page blank. Latency budget design and aggressive web-tier caching are the only mitigations — the timeout cannot be extended.
  2. Web-Tier Cache TTL Hard Cap at 86400 Seconds — MRT CDN enforces a maximum cache TTL of 86400 seconds (24 hours). TTL values set above this limit are silently clamped. Architecture documents that specify longer TTLs (e.g., 7-day catalog caches) will not behave as designed. If content genuinely needs cache lifetimes above 24 hours, an explicit cache invalidation strategy must be designed instead.
  3. SLAS Is Not Salesforce Identity — SLAS is a separate OAuth2 service from the Salesforce org's connected app OAuth infrastructure. A client ID registered as a connected app in the Salesforce org does not work with SLAS. SLAS client IDs are registered through the SLAS management interface in Account Manager. Architectures that conflate the two OAuth systems will fail silently — SLAS returns invalid_client with no further diagnostic detail pointing to this misunderstanding.
  4. Guest Basket IDs Are Token-Bound — Merge Is Not Automatic — Guest baskets are created under the guest token's subject claim. When a shopper authenticates, the registered shopper token cannot access the guest basket — calls return 403. The basket merge endpoint (POST .../baskets/actions/merge) is the only supported mechanism. If the login flow does not call the merge endpoint before discarding the guest basket reference, the shopper's pre-login cart items are silently lost.
  5. Under-Keying the Web-Tier Cache Causes Locale and Currency Cross-Contamination — A common architecture oversight is using only the URL path as the cache key for product pages. If the same URL path serves multiple locales (e.g., via Accept-Language headers or session cookies), shoppers in different locales receive each other's cached page. Cache keys must include locale, currency, and any other dimension that affects page content. Over-keying on user-specific data is equally harmful — it makes every request a cache miss.

Output Artifacts

ArtifactDescription
Stack decision recordComposable Storefront vs. SFRA decision with rationale, team capability assessment, and migration path if applicable
SLAS auth model documentSession type map (guest/registered/agent), token acquisition flows, token storage strategy, basket merge design
SCAPI endpoint mapPer-page-type list of SCAPI calls, classified as SSR-required or client-side, with latency budget per call group
Cache-key design tablePer-page-type cache-key components, TTL values (≤ 86400s), and personalized-content exclusion list
Architecture decision recordFormal ADR capturing stack, hosting, auth, caching, and integration decisions with open risks

Official Sources Used

Package files