# useProduct (https://docs.salla.dev/twilight/react/hooks/use-product)



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 [#example]

```tsx title="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 [#api]

```ts
function useProduct(
  initialProduct: Product,
  options?: UseProductOptions
): UseProductResult;
```

| Prop                 | Type      | Description                                                                                                                 |
| -------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------- |
| `initialProduct`     | `Product` | The product from your route loader. Required.                                                                               |
| `options.isPreview?` | `boolean` | Pass `true` while the product is only a list-card stand-in. When it turns `false`, the hook re-seeds from the full product. |

Returns:

| Prop      | Type                  | Description                                                                                     |
| --------- | --------------------- | ----------------------------------------------------------------------------------------------- |
| `product` | `Product`             | The current product.                                                                            |
| `reload`  | `() => Promise<void>` | Fetches the product again from the Salla SDK (with images and category) and replaces the state. |

## Gotchas [#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 [#next]

* [Product data](https://docs.salla.dev/twilight/react/data/product): every field of the product, with example values.
* [`useMoney`](https://docs.salla.dev/twilight/react/hooks/use-money) formats the price you show.
* [Loading data](https://docs.salla.dev/twilight/react/guide/loading-data) explains where `initialProduct` comes from.
* [Salla SDK and events](https://docs.salla.dev/twilight/react/guide/salla-sdk-and-events)
