Behio Storefront SDK
React Hooks

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.

On this page