Why decouple the commerce frontend
Section titled “Why decouple the commerce frontend”Traditional commerce platforms tightly couple the catalog, cart, and storefront rendering. This constrains frontend teams to the platform’s templating engine and deployment cycle. When the marketing team wants a campaign landing page or the mobile team needs product data, the monolithic storefront becomes a bottleneck.
Graph lets you treat the product catalog as a queryable data source. The Commerce platform remains the system of record for products, pricing, and inventory. Graph indexes the catalog and exposes it through GraphQL. Your frontend — whether React, Next.js, or a mobile app — queries exactly the product data it needs with the performance of a CDN-backed API.
Architecture overview
Section titled “Architecture overview”┌────────────────────────────────────────────────┐│ Commerce: Catalog Management ││ Products, categories, pricing, inventory │└───────────────────────┬────────────────────────┘ │ sync on publish ▼┌────────────────────────────────────────────────┐│ Optimizely Graph ││ Product index with full-text search, ││ faceted filtering, category navigation │└───────────┬───────────────────────┬────────────┘ │ │ ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ Web Store │ │ Mobile App │ │ (Next.js) │ │ (React │ │ │ │ Native) │ └──────────────┘ └──────────────┘Step 1: Configure catalog sync to Graph
Section titled “Step 1: Configure catalog sync to Graph”Set up the integration between Commerce and Graph so that product publishes trigger Graph re-indexing. The sync should include:
- Product names, descriptions, and metadata
- Category hierarchies and assignments
- Pricing tiers and availability
- Product images and media references
Verify the sync by publishing a test product in Commerce and confirming it appears in the Graph explorer within your expected latency window.
Step 2: Build product listing queries
Section titled “Step 2: Build product listing queries”Create GraphQL queries for common storefront patterns:
Category listing with pagination:
query CategoryProducts($category: String!, $skip: Int, $limit: Int) { Product( where: { category: { eq: $category } } orderBy: { name: ASC } skip: $skip limit: $limit ) { items { name, slug, price, thumbnailUrl, rating } total }}Search with filters:
query SearchProducts($term: String!, $minPrice: Float, $maxPrice: Float) { Product( where: { _fulltext: { match: $term } price: { gte: $minPrice, lte: $maxPrice } } ) { items { name, slug, price, thumbnailUrl, category } facets { category { name, count } } }}Step 3: Build product detail queries
Section titled “Step 3: Build product detail queries”Product detail pages need richer data including CMS editorial content:
query ProductDetail($slug: String!) { Product(where: { slug: { eq: $slug } }) { items { name, description, price, sku images { url, alt } specifications { key, value } relatedProducts { name, slug, thumbnailUrl, price } } }}Step 4: Handle cart and checkout
Section titled “Step 4: Handle cart and checkout”Graph serves read-only catalog data. Cart management, pricing calculations, and checkout remain with the Commerce platform API. Your frontend calls Graph for browsing and Commerce APIs for transactional operations.
| Operation | Source | Why |
|---|---|---|
| Product browsing | Graph | Fast, cached, CDN-backed |
| Search and filtering | Graph | Full-text search with facets |
| Add to cart | Commerce API | Requires real-time inventory check |
| Checkout | Commerce API | Requires payment processing |
When to use this pattern
Section titled “When to use this pattern”Headless commerce via Graph works best when you need multiple frontends (web + mobile + kiosk) consuming the same catalog, or when your frontend team prefers a modern JavaScript framework over the Commerce platform’s built-in rendering. If you operate a single storefront with simple requirements, the built-in Commerce frontend may be sufficient.