Products

Products are the core of your storefront. Use Product for a product detail page and ProductList for product grids with filters, search, and pagination.


Product Page

A product detail page renders a single product — it auto-detects the slug from the URL.

<Product class="max-w-7xl mx-auto px-4 py-8">
  <div class="grid grid-cols-1 md:grid-cols-2 gap-12">
    <ProductImage class="w-full aspect-square object-cover rounded-lg" />

    <div class="space-y-6">
      <ProductName class="text-3xl font-bold" />
      <div class="flex items-baseline gap-2">
        <ProductPrice class="text-2xl font-bold text-primary" />
        <ProductComparePrice class="text-lg text-muted-foreground line-through" />
      </div>
      <ProductStockCount class="text-sm text-muted-foreground" />
      <ProductDescription class="text-muted-foreground leading-relaxed" />

      <div class="flex items-center gap-4">
        <ProductQuantityActions>
          <ProductQuantityDecrementTrigger />
          <ProductQuantityInput class="w-16 text-center" />
          <ProductQuantityIncrementTrigger />
        </ProductQuantityActions>
      </div>

      <div class="flex gap-3">
        <ProductAddToCartTrigger class="flex-1" />
        <ProductToggleWishlistTrigger />
      </div>
    </div>
  </div>
</Product>

All sections read from product context — name, price, image, description, SKU, compare price, discount, stock count, and inventory status. Just include the ones you need.


Triggers

Trigger What it does
ProductAddToCartTrigger Adds the product to cart
ProductRemoveFromCartTrigger Removes it from cart
ProductToggleWishlistTrigger Toggles wishlist (adds if not present, removes if present)
ProductAddToWishlistTrigger Adds to wishlist
ProductRemoveFromWishlistTrigger Removes from wishlist
ProductOrderTrigger Initiates an order
ProductQuantityDecrementTrigger Decrements quantity by 1
ProductQuantityIncrementTrigger Increments quantity by 1

CSS Visibility with Data Attributes

Triggers set data-in-cart and data-in-wishlist attributes for CSS-based show/hide:

<ProductAddToCartTrigger
  class="data-[in-cart]:hidden w-full"
/>
<ProductRemoveFromCartTrigger
  class="hidden data-[in-cart]:block w-full"
/>

<ProductAddToWishlistTrigger
  class="data-[in-wishlist]:hidden absolute top-2 right-2"
/>
<ProductRemoveFromWishlistTrigger
  class="hidden data-[in-wishlist]:block absolute top-2 right-2"
/>

Product List

ProductList fetches products and renders them in a grid. It auto-detects category context when placed inside a Category, and reads filter/pagination state automatically.

<ProductList>
  <Grid cols={4} gap={4}>
    <CollectionView>
      <Product class="border rounded-lg p-4">
        <ProductImage class="w-full aspect-square object-cover" />
        <ProductName class="font-semibold mt-2" />
        <ProductPrice class="text-lg font-bold" />
        <ProductAddToCartTrigger class="w-full mt-4" />
      </Product>
    </CollectionView>
  </Grid>
</ProductList>

ProductList auto-picks up:

  • Filters — when inside ProductFilterProvider, reads active filters automatically.
  • Categories — when inside Category, fetches products for that category.
  • Search — when the URL has ?search=..., filters by search query.
  • Pagination — when inside ProductPaginationProvider, reads cursor state.

No props needed — just nest them.


Product Media

ProductMedia iterates over a product's media array — images, videos, or audio:

<ProductMedia>
  <Grid cols={4} gap={2}>
    <CollectionView>
      <ProductMediaItem class="aspect-square object-cover rounded" />
    </CollectionView>
  </Grid>
</ProductMedia>

Variants

ProductVariantProvider wraps option selectors. Sections auto-read the selected variant.

<Product>
  <ProductVariantProvider>
    <ProductVariantOptionRadioGroup name="Color" />
    <ProductVariantOptionSelect name="Size" placeholder="Select size" />
  </ProductVariantProvider>

  <ProductImage class="w-full aspect-square" />
  <ProductName class="text-2xl font-bold" />
  <ProductPrice class="text-3xl font-bold" />
  <ProductAddToCartTrigger />
</Product>

When a variant is selected, ProductImage, ProductPrice, ProductSku, ProductComparePrice, and ProductDiscount automatically switch to the matching variant's data.


Related Docs

  • Product Filters — URL-synced filter system
  • Product Search — Typesense autocomplete search
  • Product Reviews — Star ratings and review display
  • Recommendations — Personalized product suggestions