Skip to main content
This page is the curated reference. The complete, generated type reference lives at /kit/api/core (the resource) and /kit/api/react (CartStore), regenerated from the published typings.
The cart resource has two layers. The stateless methods map the Cart API one to one. The remembered methods add the one piece of state every storefront needs: which cart this visitor has, kept identically in the browser, a server component and a server action. On top of both sits the CartStore, the observable cart the React hooks and the web components share. The cart is server-owned and prices are recomputed on every read. Never cache cart figures beyond the current render. All money is in minor units. Shapes are on Types.
itemId is the cart line id (a uuid, item.id), not the product id. productId is what you add; item.id is what you update and remove.

Currency

A cart stores no currency of its own: it is priced per request. Every cart call (create, get, addItem, updateItem, removeItem, and so current, ensure and add) carries the client’s currency as ?currency=, so the same cart reads in SEK on one request and in EUR on the next. Switching currency never creates a new cart and never loses a line.
  • cart.currency is what every amount in that response is in. Format with it, never a constant.
  • cart.presentment says how that currency relates to the checkout: { mode, chargeCurrency, baseCurrency, exchangeRate }. In "display" mode the amounts are converted for display and the checkout charges chargeCurrency (the shop’s own). A missing presentment means mode: "base".
See Currencies.

Stateless methods

cart.create

Creates a cart and hands it back without remembering it. Passing storefrontId creates a cart bound to that campaign storefront; the binding cannot change afterwards. Check it out with checkout.start({ cartId }).

cart.get

null on 404 or 410: an expired cart is a normal answer.

cart.addItem

string | number
required
"prod_123" or 123.
number
The variant’s numeric id. Required when the product has more than one variant.
number
default:"1"
Adding the same product and variant again increments the existing line.

cart.updateItem

Sets an absolute quantity on a line.

cart.removeItem

cart.delete

Deletes the cart and also forgets it locally when it is the remembered one.

Remembered methods

cart.currentId

The remembered cart id. Makes no request.

cart.current

Reads the remembered cart and never creates one. A remembered id that no longer resolves is forgotten and reported as null. Use it wherever a missing cart is a legitimate answer: a header badge, a server-rendered cart page, any page a crawler can reach.

cart.ensure

Returns the remembered cart, or creates and remembers one. Needs writable storage: in a read-only context (a React Server Component) the cart is still created but not remembered.

cart.add

ensure() plus addItem(). It also recovers once from a stale cart: when the remembered id answers 404 or 410 it forgets it, creates a fresh cart and retries. Prefer it over ensure() followed by addItem(). On a client bound to a campaign storefront the cart it creates is bound too. A per-call storefrontId here must equal the client’s binding, or the call throws a ShopkitConfigError before any request. See Campaign storefronts.

cart.clear

Deletes the remembered cart server-side and forgets it, so the next add() starts a fresh basket. The remembered checkout session id and the shop’s store id are left alone, so a thank-you page can still confirm an order already paid for. fallbackCartId names the cart to delete when storage remembers none (the cart on screen).

CartStore

The observable cart every React hook and every web component shares, so a header badge and a cart page never disagree. While anything is subscribed it watches the client’s currency and re-reads the same cart when it changes; a read that a later switch overtook is dropped, so a slow answer can never land an older currency’s cart. It is framework-free; React reads it with useSyncExternalStore. Without React, take the page’s instance from the elements’ configure() (configure(...).cartStore) or Quickbutik.cart on a script-tag page rather than constructing a second one.
ShopkitClient
required
Cart | null
A cart read on the server. The store then starts ready, so the first paint matches the server render.

subscribe / getSnapshot

Cart | null
'idle' | 'loading' | 'ready' | 'error'
Error | null
Captured from the last failed mutation. Mutations do not throw.
number
Mutations in flight.
number
Sum of quantities, for a badge.
number
Bumped once per successful mutation made through this store, never by a load or refresh. Compare it across renders; the absolute value means nothing.

load

Reads the remembered cart with cart.current(). Never creates a cart, so mounting a badge causes no write for a visitor who only browses.

refresh

Re-reads the cart from the server.

add / updateItem / removeItem

Resolve to null on failure, with the error in the snapshot. add() creates the cart on first use. updateItem(itemId, 0) is translated into a remove.

clear / clearCart

Empties the basket through cart.clear(). A no-op (no request, no revision bump) when there is no cart.

buyNow

Adds the item to the remembered cart and starts a checkout, keeping the store in step so a badge on a page the shopper comes back to is right. Returns the start result plus cart. It does not navigate; the UI layers do.

onMutation

Be told about every successful mutation made through this store, with the cart before and after. Returns an unsubscribe. Never emitted for load, refresh or hydrate (something was read, nothing changed), nor for a failed mutation. It is what the analytics hub diffs into add_to_cart and remove_from_cart.
'add' | 'update' | 'remove' | 'clear' | 'buy-now'
Cart | null
The cart before the change.
Cart | null
The cart after the change; null after clear.

hydrate

Adopts a cart fetched elsewhere, for example by TanStack Query or a server action, so every subscriber updates.