cimplify

React Hooks Reference

All hooks from @cimplify/sdk/react with signatures, return types, and usage.

Data and commerce hooks require <CimplifyProvider />. Checkout hooks (useCheckout, useElements) require <ElementsProvider />.

All data hooks share a module-scoped cache (Map) that survives re-renders and is shared across components. Changing location via setCurrentLocation invalidates all caches since prices are location-dependent.

Data Hooks

useProducts(opts?)

OptionType
category?string
collection?string
search?string
featured?boolean
limit?number
enabled?boolean

Returns { products, isLoading, error, refetch, is_complete, pagination }.

TSX
const { products, isLoading, error, refetch, is_complete } = useProducts({
  category: 'mains',
  limit: 10,
});

useProduct(slugOrId)

Auto-detects slug vs ID format. Returns { product, isLoading, error, refetch }.

TSX
const { product, isLoading } = useProduct('jollof-rice');   // by slug
const { product: p2 } = useProduct('prod_abc123');          // by ID

useCategories(opts?)

Returns { categories, isLoading, error, refetch }.

TSX
const { categories, isLoading } = useCategories();

useCollections(opts?)

Returns { collections, isLoading, error, refetch }.

TSX
const { collections, isLoading } = useCollections();

useCollection(id)

Returns { collection, isLoading, error, refetch }.

TSX
const { collection, isLoading } = useCollection('col_summer2025');

useBundle(id)

Returns { bundle, isLoading, error, refetch }.

TSX
const { bundle, isLoading } = useBundle('bun_family_meal');

useComposite(id)

Returns { composite, isLoading, error, refetch }.

TSX
const { composite, isLoading } = useComposite('comp_build_your_bowl');

useSearch(query, opts?)

Returns { results, isLoading, error, refetch }.

TSX
const { results, isLoading } = useSearch('espresso', { limit: 5 });

useLocations(opts?)

Returns { locations, isLoading, error, refetch }.

TSX
const { locations, isLoading } = useLocations();

Commerce Hooks

useCart(opts?)

Optimistic cart state -- UI updates instantly, syncs with server after.

Return fieldType
itemsCartItem[]
itemCountnumber
subtotalnumber
taxnumber
totalnumber
currencystring
isEmptyboolean
isLoadingboolean
addItem(product, quantity?, options?) => void
removeItem(itemId) => void
updateQuantity(itemId, quantity) => void
clearCart() => void
sync() => void
TSX
const { items, total, addItem, removeItem, updateQuantity } = useCart();

// addItem signature
addItem(product, 2, {
  variantId: 'var_large',
  locationId: 'loc_01',
  quoteId: 'qt_abc',
  addOnOptionIds: ['addon_oat'],
  bundleSelections: [{ productId: 'prod_1', quantity: 1 }],
  compositeSelections: [{ groupId: 'grp_1', productId: 'prod_2' }],
  specialInstructions: 'Extra hot',
});

useOrder(orderId, opts?)

Returns { order, isLoading, error, refetch }. Supports polling for real-time order status updates.

TSX
const { order, isLoading } = useOrder('ord_abc123', {
  poll: true,
  pollInterval: 5000,  // ms, default 5000
});

// order?.status updates automatically while polling

useQuote(input, opts?)

Fetches a price quote for a product configuration. Auto-refreshes 30 seconds before expiry by default.

Input fieldType
productIdstring (required)
variantId?string
locationId?string
quantity?number
addOnOptionIds?string[]
bundleSelections?BundleSelection[]
compositeSelections?CompositeSelection[]

Returns { quote, isLoading, error, refresh, isExpired, messages }.

TSX
const { quote, isExpired, refresh, messages } = useQuote(
  {
    productId: 'prod_abc',
    variantId: 'var_large',
    addOnOptionIds: ['addon_oat', 'addon_syrup'],
    quantity: 2,
  },
  { autoRefresh: true, refreshBeforeExpiryMs: 30000 },
);

// quote?.total, quote?.breakdown, quote?.expiresAt
// messages contains pricing notes (e.g., "Bulk discount applied")

Checkout Hooks

useElements()

Returns the CimplifyElements instance from ElementsProvider, or null before initialization.

TSX
const elements = useElements();

// Access underlying element instances
const payment = elements?.getElement('payment');
const isAuthed = elements?.isAuthenticated();

useCheckout()

Returns { submit, process, isLoading }. Requires ElementsProvider.

TSX
const { process, isLoading } = useCheckout();

const result = await process({
  cart_id: cartId,
  order_type: 'delivery',
  location_id: locationId,
  enroll_in_link: true,
  timeout_ms: 180_000,
  on_status_change: (status, context) => {
    console.log(status, context.display_text);
  },
});

if (result.success) {
  router.push('/order/' + result.order?.id);
}

Important Patterns

PatternDetail
Shared cacheModule-scoped Map, survives re-renders, shared across all components.
Location invalidationChanging location clears all caches because prices are location-dependent.
Slug detectionuseProduct auto-detects slug (no underscore prefix) vs ID (prod_).
Order pollinguseOrder with { poll: true } refetches at pollInterval until terminal status.
Quote auto-refreshuseQuote refreshes 30s before expiry by default to keep prices valid.
Optimistic cartuseCart updates UI instantly, then syncs mutations to the server.