useProduct

Keep a product object live: it updates its price and stock when the customer picks options, and can be reloaded.

Use useProduct on a product page, where the price and stock must follow the options the customer selects. Give it the product your route loader returned.

Example

app/components/product/ProductPrice.tsx
import { useProduct } from '@salla.sa/twilight-theme-engine/hooks/useProduct';
import { useMoney } from '@salla.sa/twilight-theme-engine/hooks/useMoney';
import type { Product } from '@salla.sa/twilight-theme-engine/types';

export function ProductPrice({ initial }: { initial: Product }) {
  const { product } = useProduct(initial);
  const { format } = useMoney();
  return (
    <p>{product.is_out_of_stock ? 'Out of stock' : format(product.price)}</p>
  );
}

API

function useProduct(
  initialProduct: Product,
  options?: UseProductOptions
): UseProductResult;
PropTypeDescription
initialProductProductThe product from your route loader. Required.
options.isPreview?booleanPass true while the product is only a list-card stand-in. When it turns false, the hook re-seeds from the full product.

Returns:

PropTypeDescription
productProductThe current product.
reload() => Promise<void>Fetches the product again from the Salla SDK (with images and category) and replaces the state.

Gotchas

  • Live updates happen in the browser only. On the server you get initialProduct unchanged.
  • The hook listens to the SDK events product:options.updated (reloads the product), product::price.updated (updates price, regular_price, is_on_sale and weight, plus sku and barcode when the payload has them, sets sale_price to the new price when on sale, clears starting_price, and sets is_out_of_stock to false) and product::price.updated.failed (sets is_out_of_stock to true).
  • State re-seeds when initialProduct.id changes, not when the object changes. A new object for the same product does not reset the customer's choices.
  • reload ignores errors and does nothing when the SDK is missing. It does not add anything to the cart.

Next

On this page