Cart & Checkout Hooks
Server-authoritative cart state with React interactions
useCart
The hook returns cart, not a React Query data property. It also provides the
cart mutations; separate useAddToCart, useUpdateCartItem and
useRemoveCartItem exports do not exist.
import { useCart } from '@behio/storefront-sdk/react';
const {
cart, isEmpty, itemCount, error,
addItem, updateQuantity, removeItem,
clear, applyDiscount, removeDiscount, merge,
isAdding, isUpdating, isRemoving,
} = useCart();
await addItem('product-id', 1);
await updateQuantity('cart-item-id', 3);
await removeItem('cart-item-id');isEmpty considers both ordinary items and bundle lines. itemCount comes from
the server and includes the product units inside bundles. Use the bundle line
ID with the core client's cart.updateBundleQuantity() / cart.removeBundle();
then replace or revalidate the shared ['behio', 'cart'] query.
While update/removal is pending, the hook retains the last complete server
snapshot. The successful response replaces the cache, including quantity tiers,
nullable prices, taxes, discounts, availability and totals, even with
useCart({enabled: false}). A rejected mutation does not roll back newer cache
data. Disable the relevant controls using isUpdating / isRemoving and catch
the returned promise to show an actionable error.
Never compute a payable total from the requested quantity. Render unavailable
prices explicitly and suppress the payable summary/checkout when
cart.totalsAvailable === false. Use server quantityControls for adjacent
valid quantities; a local +1 need not satisfy configured steps or bundle units.
First render and session storage
Render the cart on the server. For hook-based enhancements, seed a per-request
QueryClient with the actual cart under ['behio', 'cart'], hydrate that cache and
pass the browser QueryClient to BehioProvider. Do not share a cart cache between
visitors or pass cart/auth tokens as hydration data. The browser provider notifies
hooks when its configured storage is restored.
For HTTP-only sessions, keep reads and writes in Server Components, Server
Actions or your own session-bound API. Browser hooks cannot read HTTP-only
cookies. See Next.js for native forms that also work
without JavaScript. enabled: false controls background fetching, not mutations
and not server rendering by itself.
Checkout
import type { CheckoutInput } from '@behio/storefront-sdk';
import { useCheckout, useCheckoutPreview } from '@behio/storefront-sdk/react';
const { preview, isPreviewing } = useCheckoutPreview();
const { createOrder, isCreating, error, order, reset } = useCheckout();
async function review(input: CheckoutInput) {
return preview(input);
}
async function submitReviewed(input: CheckoutInput, previewToken: string) {
return createOrder({ ...input, previewToken });
}Display the preview and obtain the shopper's confirmation before submitting.
Request a fresh preview after the cart, destination, payment, shipping or other
checkout input changes. useCheckout exposes createOrder / isCreating, not
mutateAsync / isPending. The complete CheckoutInput must reflect the shop's
settings; do not substitute hardcoded addresses, consent or payment details.
Bundle list/detail hooks restore the session before querying. useCart refreshes
their basket-dependent quantity ranges after add, update, remove, clear and merge;
useAuth does the same after login/logout. After direct core bundle mutations,
refresh the cart and cancel/invalidate both ["behio", "bundle"] and
["behio", "bundles"] query prefixes yourself.