Stonebridge CommerceDeveloper documentation

Stonebridge Commerce Storefront Developer Guide

This guide is for a store owner building their own store on the computer in front of them. The admin and the Commerce API are hosted, so nothing but your storefront runs on your machine.

One store means one project folder. If you own more than one store, give each its own folder, its own key and its own deployment, and work through this guide once per store. Nothing is shared between them.

It uses Next.js throughout, because that is what Claude builds when you follow the quick start. The API itself can be called from any server-side framework if you would rather write it yourself.

Quick start: build your storefront with Claude Code

You do not have to write this store by hand, and you do not need to be a developer. Claude Code is a coding agent that reads this guide and writes the storefront for you. The rest of this document is the reference it works from, and the reference you use when you want to check or change what it built.

The steps below assume you have never installed a developer tool in your life.

Budget about half an hour for steps 1 to 5. Step 6 is the part where you describe the store you actually want.

Step 1 — Install the Claude desktop app

This is the only thing you install by hand. Claude installs everything else for you in step 2.

You need a Claude account with a paid plan. Claude Pro is the usual choice; Max and Team also work. The free plan does not include Claude Code.

On Windows

  1. Open your web browser and go to https://claude.ai/download.
  2. Click the Download for Windows button. The file is called something like Claude-Setup.exe and lands in your Downloads folder.
  3. Open the Downloads folder and double-click that file.
  4. Windows may show a blue box saying Windows protected your PC. Click More info, then click Run anyway. This appears because the file is new to your computer, not because anything is wrong.
  5. Wait for the installer to finish. Claude opens on its own when it is done.
  6. Sign in with the email address on your Claude account.

On a Mac

  1. Open Safari or Chrome and go to https://claude.ai/download.
  2. Click the Download for Mac button. You get a file ending in .dmg in your Downloads folder.
  3. Double-click that file. A small window opens showing the Claude icon next to an Applications folder.
  4. Drag the Claude icon onto the Applications folder. That copies it in.
  5. Open Applications and double-click Claude.
  6. The first time, macOS asks whether you are sure you want to open it. Click Open.
  7. Sign in with the email address on your Claude account.

Find the Code tab

Once Claude is open and you are signed in, look along the top of the window for a tab called Code. Click it. That is Claude Code, and it is where everything in this guide happens.

If you do not see a Code tab, your plan may not include it. Check your plan at https://claude.ai/settings/billing.

Step 2 — Let Claude install the developer tools

Building a store needs a few free programs: Node.js to run the site, Git to keep its history, and the Google Cloud tools if you want to publish it to the internet later. Do not go hunting for these. Claude installs them.

In the Code tab, click New session, choose any folder when it asks, and paste this as your first message:

I am setting up this computer to build an online store, and I have never done
this before. Please walk me through it and do the work where you can.

Check what is already installed, then install whatever is missing:
- Node.js, version 20 or newer
- Git
- The Google Cloud CLI (gcloud), which I will need to publish the store later
- Anything else you know a Next.js storefront needs

Use my operating system's normal package manager where there is one, and tell
me plainly before you install anything. If a step needs my password or needs me
to click something in a browser, stop and tell me exactly what to click.

I also need accounts. For each one, tell me what it is for, whether it costs
money, and walk me through creating it one screen at a time:
- A Google Cloud account, if publishing the store needs one
- Anything else that turns out to be required

When you are finished, show me the version number of each tool so I can see it
worked.

Claude asks permission before it installs anything, so nothing happens without your say-so. Answer its questions as they come. Expect this to take ten to twenty minutes, mostly waiting for downloads.

Claude cannot create accounts or type passwords for you. When it reaches one, it stops and tells you what to do, then carries on once you say you are done.

Step 3 — Create your store and a storefront key

In the merchant admin:

  1. Register, verify your email and phone, and sign in.
  2. Create a store, then select it.
  3. Go to Store management → API keys.
  4. Create a key of type Storefront and copy the value beginning sb_storefront_.

Section 5 covers keys in more detail. The one rule that matters most: this key belongs on a server, never in browser JavaScript. Section 6 explains why, and step 5 below tells Claude to respect it.

Step 4 — Create a project folder

Make an empty folder for this store, somewhere you will find it again, and start a Claude session in it. In the Code tab, click New session and pick that folder.

Name it after the store. One folder holds one store, and a second store gets a second folder, so the name is what tells them apart later.

Keep the store's key nearby but do not paste it into the chat. Claude will tell you which file to put it in, where it stays out of your conversation history.

Step 5 — Give Claude its brief

Paste this in as your first message, replacing the two bracketed values:

Fill in both boxes above and the brief updates as you type.

I want to build an online store using the Stonebridge Commerce platform.

Read these two references before writing any code:
- The storefront developer guide:
  https://stonebridge-admin-dev-633417163058.us-west1.run.app/docs/storefront-developer-guide.md
- The OpenAPI specification:
  https://stonebridge-api-dev-633417163058.us-west1.run.app/swagger/v1/swagger.json

My store sells: [DESCRIBE WHAT YOU SELL]
The look and feel I want: [DESCRIBE THE STYLE YOU WANT]

Build it as a Next.js storefront following the guide's patterns. Specifically:
- Keep my storefront key server-side only, in .env.local, and never in browser
  JavaScript or a NEXT_PUBLIC_ variable.
- Call the Stonebridge API from server-side code, using the browser-safe proxy
  route pattern in section 9 of the guide.
- Cover product listing, product detail, cart, and checkout.

Ask me for the storefront key when you need it, and tell me which file to put it
in rather than asking me to paste it into this chat.

Claude will fetch both references, plan the work, and start building. It asks permission before creating or changing files, so you stay in control.

Step 6 — Build, look, and refine

Ask it to start the store and show you, then describe changes in plain language:

  • "The product grid should be three columns on desktop, one on mobile."
  • "Add a search box to the header that filters the catalog."
  • "The checkout button is too small and the contrast is poor."

Work in small steps and look at the result after each one. That gets you a store you actually like far faster than one long instruction.

What to do when something breaks

Paste the error into Claude — the full message, not a summary — and let it diagnose. If it is an API error, section 16 lists what each status code means, and Claude can read that section itself if you point it there.

The assistant in the admin dashboard can also answer questions about this process and about your own store's data at any point.

1. The addresses you need

Four links. You do not install any of them.

ServiceURL
Merchant admin, where you manage the storehttps://stonebridge-admin-dev-633417163058.us-west1.run.app
Commerce API, what your storefront callshttps://stonebridge-api-dev-633417163058.us-west1.run.app
API referencehttps://stonebridge-api-dev-633417163058.us-west1.run.app/swagger
An example store, to see what one looks likehttps://willow-b-farm-dev-633417163058.us-west1.run.app

These are development addresses. They can change before the platform launches, so keep the API one in .env.local rather than typing it into your code.

2. Running your storefront on your own machine

The admin and the Commerce API are hosted. You do not install them, and you do not need a database. The only thing that runs on your machine is the storefront you are building, and it talks to the hosted API over HTTPS exactly as it will once it is deployed.

From your storefront's folder:

npm run dev

That serves it at http://localhost:3000. Edit a file, save, and the page reloads. Claude can start this for you and keep it running while you describe changes.

Two settings point it at the platform. Both belong in .env.local, which is never sent to the browser and should never be committed:

STOREFRONT_API_ORIGIN=https://stonebridge-api-dev-633417163058.us-west1.run.app
STOREFRONT_API_KEY=sb_storefront_...

Section 7 covers these two in full, and section 6 explains why the key has to stay on the server.

Your store's data is the same data the admin shows. Add a product in the admin, reload your local storefront, and it is there. There is no separate test database to keep in step, and nothing to migrate.

If you run a second store, start it from its own folder on a different port, with npm run dev -- --port 3001. Each folder keeps its own .env.local, so the two never reach for each other's key.

3. Where your storefront sits

You build the storefront. Everything to its right is hosted and is not yours to run, install or configure:

Customer browser
      |
      v
Storefront application
  - renders pages
  - keeps the storefront key on the server
  - proxies cart and checkout requests
      |
      | HTTPS + X-Storefront-Key
      v
Stonebridge Commerce API   <- hosted
      |
      v
Your store's data          <- hosted

Two rules follow from that shape. Your storefront never opens a database connection, and it never lets a browser tell it which store to read: the key already says which store it is.

4. Create an account and store

  1. Open the merchant admin.
  2. Register with an email address and password.
  3. Verify the email address and phone number.
  4. Sign in.
  5. Create a store from the dashboard.
  6. Select the store before managing its catalog or settings.

The store you have selected is the one the dashboard and your keys apply to. One account can own several stores; switch between them with Switch store in the top bar. Each one gets its own project folder on your machine, so do not point a second store at a storefront you already built.

5. Create a storefront key

In the selected store:

  1. Open Store management → API keys.
  2. Create a key with type Storefront.
  3. Give it a descriptive name, such as Production storefront.
  4. Copy the value beginning with sb_storefront_.

Storefront keys are intended for catalog, cart, and checkout traffic. Secret automation keys beginning with sb_test_ use the X-Api-Key header and should not be substituted for storefront keys.

During development, keys can be viewed again in the dashboard. Production security will eventually use stricter secret-display and rotation rules.

6. Keep the key on the server

Never put a storefront key in:

  • a variable whose name begins with NEXT_PUBLIC_;
  • browser JavaScript;
  • source control;
  • screenshots, logs, or support messages;
  • a URL or query string.

Keep it in the storefront hosting provider's secret or environment-variable configuration. Browser requests should call the storefront's own server route, which adds the key when forwarding the request to Stonebridge.

7. Next.js environment

For local storefront development, create an ignored .env.local file:

STOREFRONT_API_ORIGIN=https://stonebridge-api-dev-633417163058.us-west1.run.app
STOREFRONT_API_KEY=sb_storefront_replace_with_your_key

For Cloud Run or another host, configure the same names as runtime environment variables. Store STOREFRONT_API_KEY in the host's secret manager.

8. Server-side API helper

The following helper runs only on the Next.js server:

const apiOrigin = (
  process.env.STOREFRONT_API_ORIGIN ??
  "https://stonebridge-api-dev-633417163058.us-west1.run.app"
).replace(/\/$/, "");

const storefrontKey = process.env.STOREFRONT_API_KEY;

if (!storefrontKey) {
  throw new Error("STOREFRONT_API_KEY is not configured.");
}

export async function storefrontFetch<T>(
  path: string,
  init?: RequestInit,
): Promise<T> {
  const response = await fetch(`${apiOrigin}${path}`, {
    ...init,
    cache: "no-store",
    headers: {
      accept: "application/json",
      "x-storefront-key": storefrontKey,
      ...init?.headers,
    },
  });

  if (!response.ok) {
    throw new Error(`Stonebridge API returned ${response.status}.`);
  }

  return response.json() as Promise<T>;
}

Do not import this helper into a client component.

9. Browser-safe proxy route

Cart and checkout actions originate in the browser. Add a Next.js route handler that forwards those requests and injects the key on the server:

const apiOrigin = process.env.STOREFRONT_API_ORIGIN!;
const storefrontKey = process.env.STOREFRONT_API_KEY!;

async function proxy(request: Request, path: string[]) {
  const incomingUrl = new URL(request.url);
  const targetUrl = new URL(
    `/api/storefront/${path.join("/")}${incomingUrl.search}`,
    apiOrigin,
  );

  const response = await fetch(targetUrl, {
    method: request.method,
    headers: {
      accept: request.headers.get("accept") ?? "application/json",
      "content-type":
        request.headers.get("content-type") ?? "application/json",
      "x-storefront-key": storefrontKey,
    },
    body:
      request.method === "GET" || request.method === "HEAD"
        ? undefined
        : await request.arrayBuffer(),
    cache: "no-store",
  });

  return new Response(response.body, {
    status: response.status,
    headers: {
      "content-type":
        response.headers.get("content-type") ?? "application/json",
    },
  });
}

The Willow B. Farm reference application contains a complete catch-all proxy at:

storefront/willow-b-farm/src/app/api/storefront/[[...path]]/route.ts

9b. Website content

Not everything on a store is a product. Recipes, banners, about pages, and galleries are content, managed in the admin under Content and read through these endpoints:

EndpointReturns
GET /api/storefront/content/sections?tag=recipeEvery active section carrying that tag
GET /api/storefront/content/sections/{handle}One section
GET /api/storefront/content/files?tag=spring-galleryFiles carrying that tag

Tags are the grouping mechanism. A merchant tags three sections recipe and the storefront renders a recipe index; they tag six images spring-gallery and the storefront renders a gallery. There is no separate collection object.

bodyHtml is sanitised by the API before storage against a narrow allowlist, so it is safe to render. Only active content is returned; drafts stay invisible.

With @astraion/storefront:

import { getSections, sectionAttribute } from "@astraion/storefront";

const recipes = await getSections({ tag: "recipe" });
const cookTime = sectionAttribute(recipes[0], "cookTime");

attributesJson is a free-form JSON object where a merchant can keep the few structured values HTML cannot express — a cook time, a serving count. Read it with sectionAttribute, which returns undefined rather than throwing if the merchant typed something malformed.

10. Storefront API overview

Open the hosted OpenAPI reference for the current request and response schemas.

Common storefront operations include:

MethodPathPurpose
GET/api/storefrontRead store identity and presentation settings
GET/api/storefront/productsList published products
GET/api/storefront/products/{handle}Read a published product and its variants
GET/api/storefront/catalog/navigationList the types, categories, and tags that have visible products
GET/api/storefront/collectionsList published collections
GET/api/storefront/collections/{handle}Read a collection and its products
POST/api/storefront/cartsCreate a cart
GET/api/storefront/carts/{token}Read a cart
PUT/api/storefront/carts/{token}/items/{variantId}Set an item quantity
DELETE/api/storefront/carts/{token}/items/{variantId}Remove an item
PUT/api/storefront/carts/{token}/discountApply or remove a discount
POST/api/storefront/carts/{token}/pricingQuote shipping, tax, and discounts for a destination
POST/api/storefront/carts/{token}/checkoutValidate and begin checkout

Use the schemas displayed in OpenAPI rather than copying old example payloads. The API contract will continue to evolve during development.

11. Products and publication

Store owners manage products in the hosted admin dashboard.

  • Draft products remain hidden from storefront endpoints.
  • Active products are visible.
  • Archived products are hidden.
  • Variants are separate purchasable records.
  • Inventory can be tracked by location and variant.
  • Collections organize products for navigation and merchandising.
  • productType is a merchant-defined reusable classification.
  • productCategory and productCategoryPath come from the platform taxonomy.
  • tags is an array of merchant-assigned merchandising labels.
  • templateKey selects a storefront presentation; it is default unless the merchant assigns another lowercase, hyphenated key.
  • Publication is sales-channel specific. Product and collection endpoints use the primary storefront channel unless the request includes ?channel={salesChannelHandle}.

Product list entries include productType, productCategory, templateKey and tags. Product detail additionally includes productCategoryPath. Each variant also returns taxable, inventoryPolicy, inventoryManagement, and its optional fulfillmentService. Storefronts should treat unknown template keys as default so a new admin selection never breaks rendering. A Next.js product page can resolve a template without storing framework paths in the API:

const templates = {
  default: DefaultProductTemplate,
  "featured-product": FeaturedProductTemplate,
} as const;

const ProductTemplate =
  templates[product.templateKey as keyof typeof templates] ?? templates.default;

The API evaluates scheduled publishAt and unpublishAt timestamps when a catalog request is made. A product can therefore be active in the admin while remaining hidden from a particular channel until its scheduled release.

Filtering and navigation

GET /api/storefront/products accepts these optional query parameters:

ParameterMeaning
typeProduct type handle, not its display name
categoryCategory key; matches that category and every descendant
tagTag name, case-insensitive. Repeat it to require all of the tags
searchCase-insensitive match on title or vendor. Wildcards are matched literally
sortnewest (default), price_asc, price_desc, or title

An unsupported sort returns 400. Filters combine with AND, and all of them respect the same channel and publication rules as an unfiltered list.

Do not hard-code facet values. Call GET /api/storefront/catalog/navigation for the types, category branches, and tags that currently have visible products, each with a productCount, then use the returned key as the filter value:

{
  "productTypes": [{ "key": "preserves-9f2a1c04", "label": "Preserves", "productCount": 6 }],
  "categories": [
    {
      "key": "food-beverages",
      "label": "Food & Beverages",
      "fullName": "Food & Beverages",
      "level": 0,
      "parentKey": null,
      "productCount": 11
    }
  ],
  "tags": [{ "key": "seasonal", "label": "seasonal", "productCount": 4 }]
}

Category counts roll up their descendants, so a parent's count includes products filed under its children. Facets with no visible products are omitted, so a shopper is never offered a filter that returns nothing. A product's own productCategoryPath ends with its category key, which is what links a product page back into category navigation.

If a product is missing from a storefront, confirm that it is active, has an active variant, belongs to the expected store, and has the intended inventory configuration.

12. Cart persistence

The API returns an opaque cart token when a cart is created. Store that token in the browser's local storage or a secure storefront cookie. Do not treat it as a database identifier.

A typical flow is:

  1. Create a cart.
  2. Save its token.
  3. Add or update variant quantities.
  4. Reload the cart from the token when the customer returns.
  5. Collect customer and delivery details.
  6. Quote pricing for the delivery destination.
  7. Submit checkout.
  8. Redirect to an order-confirmation page.

Handle 400, 404, 409, and 429 responses explicitly. A 409 commonly means inventory or another resource state changed.

Quoting shipping and tax

A cart alone has no destination, so its shippingTotal and taxTotal are zero. Post the delivery address to /api/storefront/carts/{token}/pricing once the address is complete to receive the same breakdown checkout will freeze:

{
  "currencyCode": "USD",
  "lines": [
    { "variantId": 41, "lineTotal": 50.0, "discountAmount": 5.0, "taxAmount": 4.5 }
  ],
  "shippingLine": {
    "title": "United States",
    "originalPrice": 7.0,
    "discountedPrice": 7.0,
    "freeShippingThresholdApplied": false
  },
  "taxLines": [{ "title": "CA sales tax", "ratePercentage": 10.0, "amount": 5.2 }],
  "discountApplications": [
    { "code": "WELCOME10", "valueType": "percentage", "value": 10.0, "amount": 5.0 }
  ],
  "subtotal": 50.0,
  "discountTotal": 5.0,
  "shippingTotal": 7.0,
  "taxTotal": 5.2,
  "total": 57.2,
  "requiresShipping": true,
  "shippingAvailable": true
}

The endpoint is read-only: it creates no order and consumes no discount usage. Re-quote whenever the destination changes, and only display a quote for the address it was calculated for. When shippingAvailable is false, the cart requires shipping and no active zone covers the destination, so checkout will be rejected.

Custom attributes set on a cart item are copied onto the order line at checkout and are visible to the merchant in the admin order detail.

13. The one credential your storefront uses

Your storefront authenticates with exactly one thing: the X-Storefront-Key header, carrying the key from section 5.

The platform issues other credentials, for the admin dashboard and for server automation. Your storefront needs none of them, and must never carry one.

14. Reading the API reference

The OpenAPI page lists every storefront endpoint with its parameters and responses. It is the authority when this guide and the API disagree, and Claude reads it as part of the brief in step 5.

The page's own Try it out buttons do not send the X-Storefront-Key header, so use them to read the shape of a response rather than to call the API. Test real calls from your storefront's server-side code.

Swagger is public on the development platform. Do not assume it stays public.

15. Deployment

A deployable storefront needs:

  • a Node.js production build;
  • STOREFRONT_API_ORIGIN set to the hosted Commerce API;
  • STOREFRONT_API_KEY mounted from a secret manager;
  • an HTTPS public URL;
  • server-side proxy routes for browser-originated writes;
  • no direct database connection.

Cloud Run is the current reference host, but storefronts may be deployed to any provider that supports server-side Next.js and secure runtime secrets.

16. Troubleshooting

401 Unauthorized

  • Confirm the correct header name is X-Storefront-Key.
  • Confirm the key is active and belongs to the intended store.
  • Confirm the value has no surrounding quotes or whitespace.

404 Not Found

  • Confirm the product or collection is published.
  • Confirm the handle is correct.
  • Confirm the cart token has not expired.

409 Conflict

  • Refresh the cart or product data.
  • Recheck inventory.
  • Resubmit using the latest resource version when an endpoint uses optimistic concurrency.

429 Too Many Requests

Honor the Retry-After response header and avoid rapid polling.

Storefront works locally but not after deployment

17. Security checklist

  • Keep your storefront key server-side.
  • Never open a database connection from your storefront.
  • Never let a browser tell your storefront which store to read.
  • Use HTTPS.
  • Validate quantities and money on the API.
  • Treat prices returned to the browser as display values, not authority.
  • Avoid logging tokens, keys, personal data, or payment information.
  • Rotate a key immediately if it is exposed.
  • Give every store, and every deployment of a store, its own key.

18. Reference implementation

The Willow B. Farm storefront is a working store built on this platform, and the closest thing to a finished example. Open it and click around. It shows:

  • server-rendered catalog pages;
  • product and collection routes;
  • a server-side API helper;
  • a browser-safe API proxy;
  • cart persistence;
  • checkout;
  • a recipe blog;
  • deployment to Cloud Run.

Point Claude at that URL if you want your store to work the same way. Your store still gets its own folder, its own key and its own deployment: nothing is shared with it.