Integrate Salesforce Commerce Cloud (SFCC) with Bolt.new by building API routes that proxy OCAPI or SCAPI calls server-side. Bolt.new generates the TypeScript client code and Next.js API routes; you store SFCC credentials in your .env file. Deploy to Netlify or Vercel to run the server-side proxy, then connect your storefront components to product catalog, cart, and checkout endpoints.
Building an SFCC-Powered Storefront with Bolt.new
Salesforce Commerce Cloud powers some of the world's largest retail brands — from Adidas to L'Oreal — through two API layers: the older Open Commerce API (OCAPI) and the newer Salesforce Commerce API (SCAPI). SCAPI is the recommended path for new integrations, offering RESTful endpoints for product catalog browsing, Shopper Login and API Access Service (SLAS) for guest and registered shopper tokens, cart and checkout management, and Einstein AI-powered product recommendations. Connecting Bolt.new to SFCC gives you a fast path from a natural-language storefront description to working product listings and cart functionality backed by enterprise inventory.
The integration architecture is dictated by Bolt.new's browser-based WebContainer runtime. SCAPI requests require a client secret for merchant-account operations and a short-lived shopper JWT for customer-facing calls — neither of which can safely live in client-side JavaScript. The correct pattern is a Next.js API route that performs the SLAS OAuth2 dance (acquiring a guest shopper token), caches that token in memory, and proxies all SCAPI catalog and cart requests through the server. Bolt.new's AI chat can generate this entire API layer from a single prompt, including TypeScript types derived from the SCAPI OpenAPI specification.
Once the API proxy is in place, Bolt.new generates React components — product grid, product detail page, mini-cart, and category navigation — that call your local API routes rather than SFCC directly. This architecture works identically in development (WebContainer preview) and on deployed Netlify or Vercel infrastructure, with the only difference being where the .env credentials are stored.
Integration method
Bolt.new generates Next.js API routes that act as a secure proxy between your storefront frontend and Salesforce Commerce Cloud's SCAPI or OCAPI endpoints. Your SFCC client credentials stay in a server-side .env file and never reach the browser. The frontend React components call your local API routes, which then authenticate with SFCC using OAuth2 client-credentials flow and forward requests to the appropriate Commerce API.
Prerequisites
- A Salesforce Commerce Cloud sandbox or production instance with SCAPI enabled
- An SFCC API client registered in Account Manager with client_credentials grant type and appropriate roles
- Your SFCC short-code, org-id, site-id, and client credentials from Account Manager
- A Bolt.new account — Pro plan recommended for larger Next.js projects
- A Netlify account for deployment and production environment variable management
Step-by-step guide
Gather Your SFCC API Credentials
Gather Your SFCC API Credentials
Before prompting Bolt.new, collect all four SFCC identifiers you will need. Log in to Salesforce Account Manager (account.demandware.com). Navigate to API Client → Create API Client. Set the grant type to client_credentials and assign the Shopper Login role plus any catalog roles needed. Copy the Client ID and Client Secret. Back in your SFCC Business Manager, find your Organization ID (starts with 'f_ecom_'), your Short Code (an 8-character string like 'kv7kzm78'), and your Site ID (e.g., 'RefArch' or your merchant site ID). The SCAPI base URL pattern is: https://{short-code}.api.commercecloud.salesforce.com. You will also need the SLAS token endpoint: https://{short-code}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{org-id}/oauth2/token. Write all five values down — you will paste them into a .env file in the next step. Never hard-code these values in source files that could be committed to a public repository.
Pro tip: If you do not have a live SFCC sandbox, request a free 30-day trial via Salesforce Trailhead. Alternatively, use the public SFCC reference storefront demo credentials available in the Salesforce Commerce SDK documentation for testing.
Expected result: You have your SFCC_CLIENT_ID, SFCC_CLIENT_SECRET, SFCC_ORG_ID, SFCC_SHORT_CODE, and SFCC_SITE_ID values ready to paste.
Prompt Bolt to Generate the SFCC API Proxy
Prompt Bolt to Generate the SFCC API Proxy
Open Bolt.new and start a new Next.js project. Use the prompt below to generate the core API proxy layer. Bolt's AI will create three Next.js API routes: one for acquiring SLAS guest shopper tokens, one for product search, and one for individual product details. It will also generate TypeScript interfaces for SFCC product and basket objects, a server-side token cache using a module-level variable (appropriate for serverless), and a reusable SFCC fetch helper that attaches the Authorization header automatically. Review the generated code carefully — confirm that all process.env references match the variable names in your .env file, that no credentials appear in any file under /app or /components, and that the token helper correctly encodes client_id:client_secret as Base64 for the SLAS client-credentials request. If the AI generates Deno.env.get() patterns from other platforms, ask it to switch to process.env for Next.js.
Create a Next.js app connected to Salesforce Commerce Cloud SCAPI. Generate these API routes: (1) /api/sfcc/token — POST route that requests a guest shopper token from SLAS using client_credentials grant, encodes client credentials as Base64 in the Authorization header, and returns the access_token; (2) /api/sfcc/products — GET route that accepts query params q and categoryId, calls SCAPI shopper-products search endpoint, and returns product hits; (3) /api/sfcc/products/[id] — GET route that fetches a single product by ID including images and price. Create a lib/sfcc.ts helper with a getCachedToken() function and a sfccFetch() wrapper. Use process.env for SFCC_CLIENT_ID, SFCC_CLIENT_SECRET, SFCC_ORG_ID, SFCC_SHORT_CODE, and SFCC_SITE_ID. Build a product grid homepage that calls /api/sfcc/products on load.
Paste this in Bolt.new chat
1// lib/sfcc.ts2const SFCC_SHORT_CODE = process.env.SFCC_SHORT_CODE!;3const SFCC_ORG_ID = process.env.SFCC_ORG_ID!;4const SFCC_SITE_ID = process.env.SFCC_SITE_ID!;5const SFCC_CLIENT_ID = process.env.SFCC_CLIENT_ID!;6const SFCC_CLIENT_SECRET = process.env.SFCC_CLIENT_SECRET!;78const BASE_URL = `https://${SFCC_SHORT_CODE}.api.commercecloud.salesforce.com`;910let cachedToken: { token: string; expiresAt: number } | null = null;1112export async function getGuestToken(): Promise<string> {13 if (cachedToken && Date.now() < cachedToken.expiresAt) {14 return cachedToken.token;15 }16 const credentials = Buffer.from(`${SFCC_CLIENT_ID}:${SFCC_CLIENT_SECRET}`).toString('base64');17 const res = await fetch(18 `${BASE_URL}/shopper/auth/v1/organizations/${SFCC_ORG_ID}/oauth2/token`,19 {20 method: 'POST',21 headers: {22 'Authorization': `Basic ${credentials}`,23 'Content-Type': 'application/x-www-form-urlencoded',24 },25 body: new URLSearchParams({26 grant_type: 'client_credentials',27 channel_id: SFCC_SITE_ID,28 }).toString(),29 }30 );31 if (!res.ok) throw new Error(`SLAS token error: ${res.status}`);32 const data = await res.json();33 cachedToken = {34 token: data.access_token,35 expiresAt: Date.now() + (data.expires_in - 60) * 1000,36 };37 return cachedToken.token;38}3940export async function sfccFetch(path: string, init?: RequestInit): Promise<Response> {41 const token = await getGuestToken();42 return fetch(`${BASE_URL}${path}`, {43 ...init,44 headers: {45 'Authorization': `Bearer ${token}`,46 'Content-Type': 'application/json',47 ...(init?.headers || {}),48 },49 });50}Pro tip: The module-level token cache works in both Next.js development (long-lived process) and serverless (each cold start re-fetches). For production at scale, move the token cache to Upstash Redis or Vercel KV to share tokens across serverless instances.
Expected result: Bolt generates lib/sfcc.ts, three API routes, TypeScript interfaces, and a product grid homepage component. The preview shows the UI shell (product cards with placeholder data or an empty state if SFCC credentials are not yet set).
Add SFCC Credentials to the .env File
Add SFCC Credentials to the .env File
In Bolt.new's file explorer, open the .env file at the project root (or create one if Bolt did not generate it). Add your five SFCC credentials as environment variables. These variables are server-side only — do not prefix them with NEXT_PUBLIC_ or VITE_, because that would expose them in the client bundle. The .env file is only read by Next.js's server-side runtime; it is never sent to the browser and should never be committed to a public Git repository. After saving the .env file, Bolt's WebContainer will automatically restart the Next.js dev server, picking up the new values. Verify the credentials loaded correctly by opening the browser DevTools Network tab, triggering the product grid, and checking that the /api/sfcc/token response returns a 200 with an access_token field. If you see a 401, the client_id:client_secret encoding is wrong — double-check that there are no trailing spaces in the .env values.
1# .env2SFCC_CLIENT_ID=your_api_client_id_here3SFCC_CLIENT_SECRET=your_api_client_secret_here4SFCC_ORG_ID=f_ecom_your_org_id_here5SFCC_SHORT_CODE=your8charcode6SFCC_SITE_ID=YourSiteIdPro tip: Add .env to your .gitignore file immediately. Bolt.new projects pushed to GitHub will expose these credentials if .env is tracked. Prompt Bolt: 'Add .env and .env.local to .gitignore.'
Expected result: The /api/sfcc/token endpoint returns a valid SLAS access_token. The product grid on the homepage loads real product data from your SFCC catalog.
Build Product Catalog and Cart Components
Build Product Catalog and Cart Components
With the API layer working, prompt Bolt to generate the storefront UI components. The product grid, product detail page, and mini-cart will all call your local API routes — not SFCC directly — so they contain no credentials and work safely in the browser. Ask Bolt to add category navigation using the /api/sfcc/categories route (you may need to generate this route too), a product detail modal or page using the /api/sfcc/products/[id] route, and a cart managed via SFCC Shopper Baskets API. For the cart, you will need an additional API route that creates a basket, adds items, and retrieves the current basket state. The basket ID should be stored in localStorage on the client — this is the standard SFCC headless pattern. Bolt can generate all of this from a follow-up prompt. When reviewing the cart code, confirm that the basket ID is read from localStorage before each API call and that the POST /api/sfcc/cart/items route passes the basketId as a path parameter in the SCAPI URL, following the pattern: /checkout/shopper-baskets/v1/organizations/{orgId}/baskets/{basketId}/items.
Add these features to the SFCC storefront: (1) Product detail page at /products/[id] showing full description, image carousel, size/color variants, price, and add-to-cart button; (2) API route POST /api/sfcc/baskets to create a new SFCC basket, returning basketId; (3) API route POST /api/sfcc/baskets/[basketId]/items to add a product; (4) API route GET /api/sfcc/baskets/[basketId] to fetch basket contents; (5) Mini-cart component in the header showing item count badge and dropdown with line items and subtotal. Store basketId in localStorage. All API routes use the sfccFetch helper from lib/sfcc.ts.
Paste this in Bolt.new chat
1// app/api/sfcc/baskets/route.ts2import { NextResponse } from 'next/server';3import { sfccFetch } from '@/lib/sfcc';45const ORG_ID = process.env.SFCC_ORG_ID!;6const SITE_ID = process.env.SFCC_SITE_ID!;78export async function POST() {9 try {10 const res = await sfccFetch(11 `/checkout/shopper-baskets/v1/organizations/${ORG_ID}/baskets?siteId=${SITE_ID}`,12 { method: 'POST', body: JSON.stringify({}) }13 );14 if (!res.ok) {15 const err = await res.text();16 return NextResponse.json({ error: err }, { status: res.status });17 }18 const basket = await res.json();19 return NextResponse.json({ basketId: basket.basketId, basket });20 } catch (error) {21 return NextResponse.json({ error: String(error) }, { status: 500 });22 }23}Pro tip: SFCC baskets expire after 14 days by default. Implement a basket recovery check on app load: try to GET the stored basketId, and if it returns 404, create a new one.
Expected result: Users can browse the product catalog, open product detail pages, add items to a cart, and see an accurate mini-cart with item counts. All data comes live from SFCC.
Deploy to Netlify and Configure Production Environment Variables
Deploy to Netlify and Configure Production Environment Variables
Bolt.new's WebContainer is a browser-based runtime — it cannot receive incoming HTTP requests from the outside world. This means SFCC webhook notifications (order status updates, inventory changes) and any OAuth callbacks cannot be tested in the preview. Deploy to Netlify to get a real server environment where your Next.js API routes run as proper serverless functions. In Bolt.new, go to Settings → Applications and connect your Netlify account via OAuth. Click Publish to trigger the first deploy. Once Bolt shows you the live Netlify URL, open the Netlify dashboard, go to Site Settings → Environment Variables, and add all five SFCC variables: SFCC_CLIENT_ID, SFCC_CLIENT_SECRET, SFCC_ORG_ID, SFCC_SHORT_CODE, and SFCC_SITE_ID. Click 'Trigger redeploy' so Netlify rebuilds with the new variables. Test the deployed URL to confirm real SFCC data loads. For SFCC order confirmation webhooks or inventory hooks, register the Netlify URL (e.g., https://your-site.netlify.app/api/sfcc/webhooks) as the endpoint in SFCC Business Manager → Order Notifications. Never use the Bolt preview URL as a webhook target — it only exists while the WebContainer is running in your browser tab.
Add a webhook receiver at /api/sfcc/webhooks that validates incoming SFCC order notification payloads using an SFCC_WEBHOOK_SECRET from .env and logs order IDs. Also add an /api/health route that returns the SFCC org ID and site ID (without the secret) to confirm environment variables are loaded on Netlify.
Paste this in Bolt.new chat
1// app/api/sfcc/webhooks/route.ts2import { NextResponse } from 'next/server';3import { createHmac } from 'crypto';45export async function POST(request: Request) {6 const body = await request.text();7 const signature = request.headers.get('x-sfcc-signature') ?? '';8 const secret = process.env.SFCC_WEBHOOK_SECRET ?? '';910 if (secret) {11 const expected = createHmac('sha256', secret).update(body).digest('hex');12 if (signature !== expected) {13 return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });14 }15 }1617 const payload = JSON.parse(body);18 console.log('SFCC webhook received:', payload.eventType, payload.orderId);19 // TODO: update database, send confirmation email, etc.20 return NextResponse.json({ received: true });21}Pro tip: Set up a Netlify branch deploy for staging so you can test SFCC sandbox events on a separate URL before pointing Business Manager webhooks at production.
Expected result: Your storefront runs on a public Netlify URL with live SFCC data. Webhook events from SFCC reach your /api/sfcc/webhooks endpoint and are logged.
Common use cases
Headless Storefront Prototype
Build a custom React storefront that reads live product catalog data, category trees, and inventory from an existing SFCC instance. Product managers can prototype new page layouts and merchandising strategies without touching the SFCC back-end.
Create a Next.js headless storefront connected to Salesforce Commerce Cloud SCAPI. Add an API route at /api/sfcc/products that fetches products from the catalog using SCAPI's shopper-products endpoint. Use a guest shopper token obtained from SLAS. Display results in a responsive product grid with name, image, price, and add-to-cart button. Store SFCC_CLIENT_ID, SFCC_ORG_ID, SFCC_SHORT_CODE, and SFCC_SITE_ID in .env.
Copy this prompt to try it in Bolt.new
Cart and Mini-Cart Widget
Embed an SFCC-connected cart widget into an existing marketing site or CMS-driven page. The widget shows item count, line items, and totals sourced from SFCC's Shopper Baskets API, allowing unified cart management across channels.
Add a cart system using Salesforce Commerce Cloud SCAPI Shopper Baskets. Create API routes for GET /api/sfcc/cart, POST /api/sfcc/cart/items, DELETE /api/sfcc/cart/items/:id. Store the basket ID in localStorage. Build a mini-cart dropdown component showing item thumbnails, quantities, unit prices, and a checkout button. All SFCC credentials must stay in .env.
Copy this prompt to try it in Bolt.new
Product Search and Filtering Dashboard
Create an internal merchandising tool where buyers can search SFCC product catalog, filter by category, price range, and attributes, and preview how products will appear on the storefront — all powered by SCAPI's product-search endpoint.
Build a product search dashboard using SFCC SCAPI shopper-product-search. Create a Next.js API route at /api/sfcc/search that accepts q, categoryId, minPrice, maxPrice query params. Display results in a sortable data table with product ID, name, category, price, and inventory status. Add faceted filter sidebar. Store all SFCC credentials in .env as SFCC_CLIENT_ID, SFCC_ORG_ID, SFCC_SHORT_CODE, SFCC_SITE_ID.
Copy this prompt to try it in Bolt.new
Troubleshooting
SLAS token endpoint returns 401 Unauthorized even with correct credentials
Cause: The API client in Salesforce Account Manager does not have the correct grant type (client_credentials) or is missing the Shopper Login role, or the channel_id in the request body does not match the SFCC_SITE_ID.
Solution: In Account Manager, verify the API client has both 'Shopper Login' and 'Catalog' roles, and that 'Allowed Grant Types' includes 'client_credentials'. Confirm SFCC_SITE_ID matches the exact Site ID in Business Manager (case-sensitive). Also verify that the Base64 encoding includes no trailing newlines — use Buffer.from() in Node.js rather than btoa() which may add newlines.
1// Verify encoding in Node.js REPL or Bolt terminal2const id = 'your_client_id';3const secret = 'your_client_secret';4console.log(Buffer.from(`${id}:${secret}`).toString('base64'));Product images return 403 Forbidden when loaded in the browser
Cause: SFCC product image URLs typically point to a Content Delivery Network domain (e.g., edge.disstg.commercecloud.salesforce.com) that may have CORS restrictions or require authentication for certain image libraries.
Solution: For sandbox environments, images may require the site to be published with image permissions enabled in Business Manager under Merchant Tools → SEO → Image Settings. For production, ensure the CDN domain is whitelisted in your Next.js next.config.js images.remotePatterns. Prompt Bolt: 'Add the SFCC CDN domain to next.config.js remotePatterns for next/image optimization.'
1// next.config.js2module.exports = {3 images: {4 remotePatterns: [5 {6 protocol: 'https',7 hostname: '*.commercecloud.salesforce.com',8 },9 {10 protocol: 'https',11 hostname: '*.disstg.commercecloud.salesforce.com',12 },13 ],14 },15};SFCC webhook events never arrive at the Netlify deployment
Cause: Bolt.new's WebContainer preview cannot receive incoming HTTP traffic — it only exists inside the browser tab. SFCC Business Manager was likely configured with the Bolt preview URL instead of the deployed Netlify URL.
Solution: Deploy to Netlify first (Settings → Applications → Connect Netlify → Publish). Copy the permanent *.netlify.app URL. In SFCC Business Manager, go to Administration → Operations → Services → Notification Services and update the webhook endpoint to your Netlify URL. Webhook delivery to the WebContainer preview is architecturally impossible — always use the deployed URL.
TypeScript build fails with 'Cannot find module @commercecloud/sdk' or similar SFCC SDK errors
Cause: Bolt may have generated import statements for official SFCC JavaScript SDKs like commerce-sdk or commerce-sdk-isomorphic that require native modules not available in WebContainers.
Solution: Replace SDK-based imports with direct fetch() calls using the sfccFetch helper from lib/sfcc.ts. The commerce-sdk-isomorphic package is pure JavaScript and should work, but commerce-sdk requires Node.js native crypto modules that fail in WebContainers. Prompt Bolt: 'Replace any commerce-sdk imports with direct fetch calls using the sfccFetch helper. Do not use commerce-sdk or commerce-sdk-isomorphic.'
Best practices
- Never prefix SFCC credentials with NEXT_PUBLIC_ — all five SFCC environment variables must remain server-side only and inaccessible from the browser bundle.
- Cache the SLAS guest token server-side (module-level variable or Redis) with a buffer before expiration — SFCC tokens are valid for 30 minutes and re-fetching on every request adds significant latency.
- Store the shopper basket ID in localStorage and check for basket expiry on app initialization; recreate the basket silently if a 404 is returned.
- Use SFCC's sandbox environment for all Bolt.new development and testing — sandbox credentials are isolated from production and cannot accidentally process real orders.
- Register SFCC webhook endpoints only after deploying to Netlify or Vercel; the Bolt WebContainer preview URL is ephemeral and cannot receive incoming HTTP connections.
- Add SFCC_SHORT_CODE and SFCC_ORG_ID to the type-checking layer by creating a lib/env.ts file that throws at startup if any required variable is missing, preventing cryptic runtime errors.
- Use SCAPI (Salesforce Commerce API) for all new integrations rather than the older OCAPI — SCAPI uses OAuth2 Bearer tokens and has better rate limits and OpenAPI documentation.
- Implement request deduplication on the product search API route using a simple in-memory cache keyed by query string to reduce SCAPI quota consumption during development.
Alternatives
BigCommerce offers a developer-friendly REST and GraphQL Storefront API with simpler OAuth setup than SFCC — a better starting point for mid-market brands not already invested in the Salesforce ecosystem.
HubSpot Commerce Hub handles product catalog, quotes, and payments with a simpler API and free tier — suitable for B2B or service businesses that need CRM-native commerce without enterprise SFCC complexity.
Marketo (also Salesforce-owned) handles marketing automation and lead nurturing; combine it with SFCC for post-purchase email flows rather than using it as a commerce platform replacement.
WooCommerce REST API is far simpler to integrate for small to mid-size stores already on WordPress and does not require enterprise Salesforce licensing.
Frequently asked questions
Does Bolt.new work with Salesforce Commerce Cloud OCAPI as well as SCAPI?
Yes. Both OCAPI (older, XML/JSON, session-cookie auth) and SCAPI (newer, REST, OAuth2 Bearer) work through the same Next.js API route proxy pattern. SCAPI is recommended for new projects because it has better OAuth2 support and an official OpenAPI spec. If your SFCC instance is older and only exposes OCAPI, prompt Bolt to use OCAPI endpoints with Basic auth instead of SLAS tokens.
Can I test the SFCC cart and checkout flow in Bolt's preview before deploying?
Outbound API calls to SFCC (token acquisition, product search, basket creation) all work in Bolt's preview because they are outbound HTTP requests from the WebContainer. What does not work in preview is receiving SFCC webhook notifications for order confirmations — those require a public URL. Test the shopping flow in preview, but deploy to Netlify before testing end-to-end order webhooks.
How do I handle registered shoppers (logged-in customers) versus guest shoppers?
The guest shopper flow uses client_credentials to obtain a guest JWT from SLAS. For registered shoppers, SLAS also supports an authorization_code_pkce flow that redirects the user to an SFCC-hosted or custom login page and returns a shopper-specific token. Prompt Bolt to add a /api/sfcc/auth/login route that generates the PKCE code challenge and redirects to the SLAS authorization endpoint. Store the shopper token in an httpOnly cookie on the server.
Will native SFCC SDK packages like commerce-sdk work inside Bolt.new?
The commerce-sdk-isomorphic package (pure JavaScript) should work in Bolt.new's WebContainer. The older commerce-sdk package may fail because it relies on Node.js native crypto APIs. If you encounter module resolution errors, use direct fetch() calls via the sfccFetch helper instead of the SDK — the raw SCAPI REST calls are straightforward and give you more control.
How do I set up SFCC environment variables on Netlify after deploying from Bolt?
After clicking Publish in Bolt.new, go to your Netlify dashboard, select the site, and navigate to Site Settings → Environment Variables. Add SFCC_CLIENT_ID, SFCC_CLIENT_SECRET, SFCC_ORG_ID, SFCC_SHORT_CODE, and SFCC_SITE_ID with their production values. Then click Deploys → Trigger Deploy → Deploy Site to rebuild with the new variables. Your .env file in Bolt only applies during WebContainer development.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation