Skip to main content

usePriceBreakdown

Gives you a live, itemized breakdown of the current configuration's price: base price, per-attribute charges, script-engine adjustments, and BOM costs, grouped and totalled. Reach for it when you want to render a "price details" panel that stays in sync as the user changes options.

Getting the controller

import { usePriceBreakdown } from "@expivi/product-configurator";

const controller = usePriceBreakdown(configurator);

The controller wires itself to the product-rules engine and fetches a fresh breakdown (debounced) whenever the configuration settles. If the configurator is already READY, an initial fetch is scheduled immediately.

Example: rendering a price breakdown panel

import { usePriceBreakdown } from "@expivi/product-configurator";

const controller = usePriceBreakdown(configurator);

const unsubscribeData = controller.subscribe(data => {
if (!data) {
render("No price available");
return;
}

const lines = Object.values(data.groups)
.flatMap(group => group.items)
.map(item => `${item.name}: ${formatMoney(item.amount, data.currency)}`);

render(lines, `Total: ${formatMoney(data.total, data.currency)}`);
});

const unsubscribeBusy = controller.subscribeBusy(busy => toggleSpinner(busy));
const unsubscribeError = controller.subscribeError(error => {
if (error) showError(error);
});

// On teardown:
unsubscribeData();
unsubscribeBusy();
unsubscribeError();
controller.destroy();

The PriceBreakdown data shape:

  • productCid — the main product's configuration id
  • total — the grand total
  • currency — currency code the amounts are expressed in
  • groups — a record keyed by PriceableType (base_price, attributes, script_engine, bom). Each group has items (each with identifier, name, amount, priceableType) and a subtotal.

API

data

The last-fetched PriceBreakdown, or null before the first successful fetch or when there is no main product. Read it once, or subscribe to updates.

const total = controller.data?.total ?? 0;

isBusy

true while a fetch is in flight. Use it to drive a loading indicator.

error

The last error message, or null. Set when a fetch fails (canceled requests are ignored).

subscribe(callback)

Registers a callback that fires with the new PriceBreakdown | null on every update. Returns an unsubscribe function.

const unsubscribe = controller.subscribe(data => updateUi(data));

subscribeBusy(callback)

Subscribes to busy-state changes. Returns an unsubscribe function.

subscribeError(callback)

Subscribes to error changes (string | null). Returns an unsubscribe function.

refresh()

Forces an immediate fetch. Rarely needed — the controller refreshes automatically on configuration changes — but useful to re-fetch on demand. Resolves once the fetch completes.

destroy()

Detaches the rules-engine subscription, clears any pending debounce, and drops all subscribers. Call it when your component unmounts.