Direct-browser storefront
Bootstraps in the browser from one store ID and completes the capability-gated, idempotent pending-order journey, with an always-available guest order-status form.
- Store ID goes in
public/headless-config.json
Headless commerce, without the fragmented stack
Build a tailored storefront, mobile app, marketplace or connected experience while 1ecomm owns the hard commerce rules behind catalog, cart, checkout preparation and non-hosted order placement.
Developer preview: catalog, anonymous cart, checkout preparation, hosted checkout handoff, capability-gated non-hosted order placement and signed commerce-event webhooks are deployed. Direct payment capture and refunds remain server-controlled operations rather than public browser APIs.
$ npm create @1ecomm/storefront my-shop
* Store ID
| YOUR_STORE_ID
| OK Store on api.1ecomm.com
| catalog, cart, checkout-preparation
| OK Catalog reachable
* Framework React · Vue
* Colour indigo of 24
| OK 20 files in my-shop/
$ npm run devFastest start
The 1ecomm CLI asks for your store ID, checks it against the live platform before it asks anything else, and writes a storefront connected to your real catalog, stock and prices.
The publishable key, API URL and capability list are discovered from the store ID. The only value written into your project is the store ID itself.
A wrong or unprovisioned store ID fails at the first prompt with what to fix, instead of producing a project that builds and then fails in the browser.
Checkout and order lookup are scaffolded only when your store’s capabilities allow them, so you never ship a page that can only fail.
Choose from 24 palettes in light, dark or follow-the-system. Changing the look later is an attribute on the page, not a rebuild.
Interactive
npm create @1ecomm/storefront@latest my-shopScripted, for CI
npx @1ecomm/cli init my-shop \
--store-id YOUR_STORE_ID \
--framework react \
--palette indigo \
--appearance system \
-y --installOpen the 1ecomm CLI Field Guide How headless works
Headless separates presentation from commerce operations. Your team controls every pixel and interaction; the API remains the authority for data and business rules.
React, Next.js, Angular, Flutter, Ionic, WordPress, kiosks and future channels.
Tenant resolution, product projections, cart lifecycle and eligible checkout choices.
Catalog, inventory, pricing, shipping, fulfillment, payment configuration and governance.
Integration guide
Each starter discovers the browser-safe runtime for an already-provisioned store. Follow the server responses; never recreate commerce totals, eligibility or payment capability in the client.
Replace only storeId in the starter’s headless-config.json. The bootstrap endpoint returns public runtime values for a store that an operator has already provisioned. Unknown stores fail closed; they never fall back to sample products.
// headless.config.json — the only value you replace
{ "storeId": "YOUR_STORE_ID" }
const runtime = await fetch(
`https://api.1ecomm.com/v1/headless/stores/${storeId}/config`
).then(r => r.json());
const response = await fetch(
`${runtime.data.apiUrl}/v1/headless/products?limit=12`,
{ headers: { 'x-publishable-key': runtime.data.publishableKey } }
);
if (!response.ok) throw new Error('Catalog unavailable');
const catalog = await response.json();Create the cart once and retain the returned hc_… bearer capability in secure shopper-session storage. Send it as x-cart-token on later cart calls.
const created = await fetch('/v1/headless/carts', {
method: 'POST',
headers: { 'x-publishable-key': PUBLIC_KEY }
}).then(r => r.json());
// Keep this bearer capability out of URLs, logs and analytics.
sessionStorage.setItem('cart_token', created.cartToken);Use product and variant IDs returned by the catalog. A product with options needs the chosen variantId. Render the cart projection returned by the API—price, promotion and totals are server-calculated. Never automatically retry mutations after an uncertain network result.
Save bounded guest contact and addresses with PATCH /v1/headless/carts/current/checkout. Render only returned shipping and checkout-ready payment methods, then persist selections using their returned IDs.
Resolve every field in missing[], then inspect the selected payment method. Only when it explicitly returns requiresHostedCheckout: false and canPlaceOrder: true, call POST /v1/headless/carts/current/checkout/order with a caller-owned Idempotency-Key of 1–120 characters.
const intent = crypto.randomUUID(); // retain across uncertainty
const placed = await fetch('/v1/headless/carts/current/checkout/order', {
method: 'POST',
headers: {
'x-publishable-key': PUBLIC_KEY,
'x-cart-token': CART_TOKEN,
'Idempotency-Key': intent
}
});If the order response is lost or times out, retry with the same cart token and the exact same idempotency key. A successful response returns a pending order confirmation; it does not authorize or capture payment. Hosted card and wallet methods must use a future hosted flow and are rejected by this command.
Start with your stack
Prefer a reference project for a specific stack? Each one needs a single store ID, discovers everything else at runtime, and fails closed: configuration or API failures are visible, and no project substitutes synthetic commerce data. Every project runs a live journey against the deployed API in its own CI.
Bootstraps in the browser from one store ID and completes the capability-gated, idempotent pending-order journey, with an always-available guest order-status form.
public/headless-config.jsonBootstraps on the server and exposes only constrained routes, including one allow-listed order-lookup proxy, so it never becomes an open proxy to the API.
headless.config.jsonStandalone components and signals. The runtime is bootstrapped before any commerce call and the cart capability is restored from session storage.
public/headless-config.jsonAn Ionic React reference with an order-status card, verified by a live journey in a Pixel 7 browser profile.
Native secure storage, deep links, signing and store submission are not yet qualified.
public/headless-config.jsonA typed Dart client and native widget UI. The compiled web build creates an order, reloads and reopens it by number and email.
Signed builds, device installation and store submission are not yet qualified.
assets/headless-config.jsonA server-side catalog client, a Gutenberg block and an [onecomm_storefront] shortcode for cart, checkout preparation and order lookup. Shopper tokens stay in HttpOnly cookies.
It does not collect payment.
the onecomm_store_id settingCatalog, cart, checkout preparation, non-hosted order placement and order lookup. Resolves its API URL and key from one store ID and rejects a mismatched bootstrap.
HeadlessCommerceClient.forStore({ storeId })Catalog, cart, checkout and customer operations, with an optional service provider that boots in a real Laravel 12 application. Tested on PHP 8.2–8.4.
the client constructorCatalog, cart, checkout and customer operations, with an optional Railtie that boots in a real Rails 7.2 application. Tested on Ruby 3.1–3.4.
the client constructorSecurity by design
The store bootstrap returns public values only. Commerce scope is still derived from its configured publishable key, while cart tokens remain bearer credentials. Keep tokens out of URLs, telemetry and unrelated origins. Missing, expired, unknown and cross-store cart tokens share the same not-found response to avoid leaking tenancy.
Build beyond the template
Start with the CLI or a maintained starter, prove the live journey, and shape your channel around a single commerce core.