> ## Documentation Index
> Fetch the complete documentation index at: https://discountkit.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Component

> Drop <dkl-price> into your theme markup and configure it with data-* attributes

A web component is the `<dkl-price>` tag written directly into your theme's Liquid. On a
**product page** it needs **zero attributes** — it clones a pre-staged carrier and renders
the primary product's price server-side.

## Usage

On a product page, add the `<dkl-price>` web component — it renders the primary product's price server-side:

```html theme={null}
<dkl-price></dkl-price>
```

<Tip>
  #### Pairing with the volume picker

  To let `<dkl-price>` own the price display, set the
  volume picker's price target to `none` (`data-price-target="none"`) and hide the theme's
  native price. The picker then only emits tier-change events, and `<dkl-price>` is the single
  element that updates.
</Tip>

<Warning>
  #### Beta Limitation for Web Components: Single Product Context

  During beta of the DKL Live Components, a web component is only recommended for product pages / where the products shown on the page are static on page load.

  For use on a page where new product instances are loaded in via the Section Rendering API / Ajax (such as a paginated collection page for example) we recommend using the app block
  instead. See [App blocks vs. Web Components](/components/app-blocks-vs-web-components).
</Warning>

## Reacting to changes

`<dkl-price>` emits a `discount-kit-live:price:change` event whenever its displayed price
updates — the recommended hook for running your own code when the price moves. It carries the
previous and new price (see the [Events](/components/price/events#price-change) reference). See
[Listen for price changes](#examples) below.

Two narrower alternatives:

* **Listen for the tier event** — the volume picker's
  `discount-kit-live:volume-discount:tier-change`, e.g. to read the selected tier's quantity.
  See [Listen for tier changes](#examples).
* **Watch the discounted state** — if you only care about whether *this* element is showing a
  discount, observe its `data-dkl-discounted` attribute (set while a tier is active) with a
  `MutationObserver`:

```js theme={null}
// Handles any number of <dkl-price> elements on the page
document.querySelectorAll('dkl-price').forEach((price) => {
  new MutationObserver(() => {
    const discounted = price.hasAttribute('data-dkl-discounted')
    // e.g. flag the surrounding card while a discounted tier is selected
    price.closest('.product-card')?.classList.toggle('is-discounted', discounted)
  }).observe(price, { attributes: true, attributeFilter: ['data-dkl-discounted'] })
})
```

## Examples

For the full list of `data-*` attributes you can set, see
[Styling & Data Attributes](/components/price/styling-and-data).

```liquid Override attributes + tokens theme={null}
<dkl-price
  data-show-savings="true"
  data-savings-format="amount"
  data-savings-label="You save"
  style="
    --dkl-price-font-size: 1.4rem;
    --dkl-price-font-weight: 700;
    --dkl-price-sale-color: #c0392b;
    --dkl-price-compare-opacity: 1;
  "
></dkl-price>
```

```js Listen for price changes theme={null}
// The recommended hook: fires whenever the displayed price updates, with the
// previous and new price states.
document.addEventListener('discount-kit-live:price:change', (event) => {
  const { productId, previousPrice, currentPrice } = event.detail.resource

  const fmt = (cents) =>
    (cents / 100).toLocaleString(undefined, {
      style: 'currency',
      currency: window.Shopify?.currency?.active ?? 'USD',
    })

  console.log(
    `Product ${productId}: ` +
      `${previousPrice ? fmt(previousPrice.priceCents) : '—'} → ${fmt(currentPrice.priceCents)}` +
      (currentPrice.discounted ? ' (discounted)' : ''),
  )
})
```

```js Listen for tier changes theme={null}
// React to volume-tier selections to drive your own UI alongside the price —
// here, a custom "Buy N at X each" summary element somewhere on the page:
//   <p data-tier-summary="7820000000001" hidden></p>
const summary = document.querySelector('[data-tier-summary]')

const money = (major) =>
  major.toLocaleString(undefined, {
    style: 'currency',
    currency: window.Shopify?.currency?.active ?? 'USD',
  })

document.addEventListener('discount-kit-live:volume-discount:tier-change', (event) => {
  const { productId, currentTier } = event.detail.resource

  // Scope to the product this summary belongs to — handy when several pickers
  // / prices share a page (e.g. the main product plus recommendations).
  if (productId !== Number(summary.dataset.tierSummary)) return

  // currentTier is null when the shopper clears their selection.
  if (!currentTier) {
    summary.hidden = true
    return
  }

  // unitPriceCents is the per-item price; discountAmount is a percentage for
  // 'percentage' tiers, or a major-unit amount for 'fixedAmount' tiers.
  const { quantity, unitPriceCents, discountType, discountAmount } = currentTier
  const saving =
    discountType === 'percentage' ? `${discountAmount}% off` : `${money(discountAmount)} off each`

  summary.hidden = false
  summary.textContent = `Buy ${quantity}+ at ${money(unitPriceCents / 100)} each — ${saving}`
})
```

## Next steps

<CardGroup cols={2}>
  <Card title="Styling & Data Attributes" icon="palette" href="/components/price/styling-and-data">
    Every `data-*` attribute, `--dkl-*` token, and CSS part.
  </Card>

  <Card title="App block" icon="puzzle-piece" href="/components/price/app-block">
    The no-code, theme-editor placement.
  </Card>
</CardGroup>
