Skip to content
Kitenzo Headless is currently invite-only. To enable it on your store, email support@kitenzo.com.

Hooks

All hooks require a <KitenzoProvider> ancestor (except where noted). Provider hooks useKitenzo and useSettings are documented on the Provider & client page.

Fetch the list of published bundles on mount.

const { bundles, isLoading, error, refetch } = useBundles();
FieldTypeDescription
bundlesBundle[]Published bundles (no product data).
isLoadingbooleanInitial load state.
errorError | nullFetch error, if any.
refetch() => voidRe-run the request.

Fetch a single bundle’s full detail (sections + products + variants). Supports SSR hydration.

const { bundle, isLoading, error, refetch } = useBundle(42, { initialData });
ParamTypeDescription
idnumberBundle ID.
options.initialDataBundleDetailPre-fetched data (e.g. from a server loader). Skips the initial client fetch.

Returns { bundle: BundleDetail \| null, isLoading, error, refetch }.

Wraps createBundleBuilder with React state. Tracks the customer’s selection, section navigation and validity.

const b = useBundleBuilder(bundle);
b.addItem(sectionId, variantId, 1);
b.updateQuantity(sectionId, variantId, 3);
b.removeItem(sectionId, variantId);
b.nextSection();

State (read):

FieldTypeDescription
selectionsSectionSelectionsRecord<sectionId, BundleSelection[]>.
currentSectionIndexnumberActive section (0-based).
currentSectionBundleSection | nullActive section object.
isSectionValidbooleanCurrent section meets its min/max.
isValidbooleanAll sections meet min/max.
isCompletebooleanValid and all rules pass and required products present.
allItemsBundleSelection[]Flat list of all selections.
errorsValidationError[]Limit-rule / required-product violations (empty when valid).

Methods (write): addItem(sectionId, variantId, quantity?), removeItem(sectionId, variantId), updateQuantity(sectionId, variantId, quantity), reset(), nextSection(), prevSection(), goToSection(index), getSectionQuantity(sectionId).

useBundlePrice(bundle, selections, options?)

Section titled “useBundlePrice(bundle, selections, options?)”

Compute the price locally (no API call). Recomputes instantly as selections change and formats with the shop’s money format.

const price = useBundlePrice(bundle, builder.selections);
// price.formattedDiscountedPrice → "$40.50"
FieldTypeDescription
originalPricestring | nullRaw, e.g. "45.00".
discountedPricestring | nullRaw, e.g. "40.50".
formattedOriginalPricestring | nulle.g. "$45.00".
formattedDiscountedPricestring | nulle.g. "$40.50".
discountTypestring | null'percentage' | 'fixed' | 'price' | null.
discountValuestring | nullDiscount amount.
currencystring | nullCurrency label.
hasDiscountbooleanWhether a discount applies.

options.currency overrides the shop currency (defaults to settings.currency or 'USD'). All fields are null when there are no selections.

Submit a selection via client.submitBundle, tracking loading/error state.

const { addBundleToCart, isLoading, error, lastResult } = useBundleCart();
const result = await addBundleToCart(bundle, builder.selections, { countryCode: 'US' });
// result: SubmitBundleResult { configuredBundleId, variantId, productId, discount, subscriptionId, pricing }
FieldTypeDescription
addBundleToCart(bundle, selections, { countryCode? }) => Promise<SubmitBundleResult>Validate + configure the bundle on the server.
isLoadingbooleanSubmission in flight.
errorError | nullSubmission error.
lastResultSubmitBundleResult | nullMost recent result.