Skip to main content
@craveup/storefront-sdk@2.0.1 is the supported TypeScript client for the public API at /api/v1/storefront. Version 2 has no browser API-key option and is a deliberate major-version migration from the published 1.x contract.

Install and configure

Create separate server and browser clients. A server client has no session or JWT provider; use it only for anonymous published calls:
A browser client owns the caller-provided, tab-scoped stores:
The client ignores caller-supplied authorization credentials and obtains customer auth only from getAuthToken. Private API keys are not a Storefront SDK option. The exact typed method surface is the complete public JSON transport API; raw request helpers are not exported, and the navigation-only hosted-storefront redirect is deliberately unwrapped. Do not pass the browser client, its store, or its token provider into a Server Component, server action, or route handler. Every remote baseUrl must use HTTPS. Plain HTTP is accepted only for the exact loopback hosts localhost, 127.0.0.1, and [::1]; a phone-accessible LAN host such as 192.168.x.x is not loopback. Redirect responses are rejected rather than followed. Async getAuthToken resolution uses the same timeout as the network response. defaultTimeoutMs and a per-call timeoutMs start before the token lookup, so a provider that does not settle produces a StorefrontTimeoutError without sending a request. Scope stored data as follows: Reject malformed or unknown stored versions instead of casting unvalidated JSON. The Next.js, React, and Expo quickstarts provide complete adapters. Within one client instance, the SDK serializes session-store mutations per location, including async SecureStore adapters. It persists revisions monotonically, coalesces identical concurrent ordering-session starts, and serializes different starts for the same location. Separate client instances or processes need coordination from the application or storage adapter.

Authorization model

  • Published merchant, location, menu, product, distance, order-time, and gratuity calls are anonymous and never receive the customer JWT.
  • orderingSessions.start returns a purpose-limited cart capability and saves it through sessionStore.
  • Cart calls attach the capability, current revision, and an idempotency key where required.
  • Customer profile, order, address, saved-payment, and loyalty history calls use the customer JWT.
  • Receipt access uses receiptToken and sends it only as X-Receipt-Token.
Use tab-scoped storage for browser capabilities. Clear the guest capability after claim, deletion, expiry, or terminal checkout handling; after claim, keep only the authoritative cart revision if customer-authenticated access continues. Clear the merchant-scoped JWT on logout and a receipt capability after terminal display or expiry. Never put capabilities or customer JWTs in URLs, public environment variables, logs, source maps, HTML, or analytics.

Catalog and ordering

locations.getOrderingReadiness() is an anonymous, side-effect-free GET. Use it to check a fulfillment method without creating a cart; omit the second argument to use the takeout default.

Checkout and terminal result

The PaymentIntent client secret is browser-usable but still sensitive: keep it in memory and do not log it or place it in a URL. Use includeCustomerContext: true only when a signed-in shopper still has a guest capability and payment creation needs Stripe customer association. Omit it for guest checkout. A claimed cart already uses the customer JWT because its guest capability has been cleared.

Customer authentication

After storing the JWT for the current tab, use customer.getProfile, customer.orders, customer.addresses, customer.savedPayments, loyalty.ledger, and loyalty.claims.

Receipts

Receipt links place the capability in the URL fragment. Capture it, immediately remove the fragment with history.replaceState, and keep it only in tab-scoped storage for that receipt.

Errors and concurrency

StorefrontClientStateError is a typed local preflight failure. For example, CUSTOMER_AUTH_REQUIRED means a customer-authenticated method was called without an available JWT, so no network request was sent. StorefrontProtocolError.reason is EMPTY_RESPONSE or INVALID_JSON for a successful response that violates the JSON contract. retryAfterMs is a bounded millisecond delay parsed from Retry-After; it is undefined when the API did not provide a usable value. On CART_CONFLICT, fetch the cart again before presenting a retry. Reuse an explicit idempotency key when your application deliberately retries the same logical mutation. GET /locations/{locationId}/redirect is a navigation-only REST operation and is intentionally not part of the typed SDK method surface. Navigate a browser or native in-app browser to it directly when entering Crave’s hosted storefront; do not fetch it as JSON with the Storefront client. SDK requests reject redirect responses and never follow them.

Browser-origin onboarding

Register every exact browser origin with Crave before testing from a browser. The origin includes its scheme, hostname, and any non-default port; local, preview, and production origins are separate registrations. Wildcards are not accepted. Native mobile requests normally omit the browser Origin header, but an Expo web deployment still needs registration.