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

# App blocks vs. Web Components

> The two ways to place a Live Component, and when to use each

Every Live Component can be placed two ways. They render the **same component**
from the **same data** — the difference is who places it, how it's configured, and where
it's allowed to go.

* **App blocks** — added through the **theme editor**. No code; every setting is a control
  in the editor. The right choice for most merchants, and the only way to render inside
  **product cards** on collection pages.
* **Web Components** — the `<dkl-*>` element written **directly into your theme's
  Liquid**. Configured with `data-*` attributes and `--dkl-*` CSS. For developers
  customizing a theme by hand. (These are labelled "Web Components" on each component page.)

## At a glance

|                                      | App block                                | Web Component                     |
| ------------------------------------ | ---------------------------------------- | --------------------------------- |
| **Added by**                         | Theme editor (drag-and-drop)             | Hand-written in theme Liquid/HTML |
| **Configuration**                    | Editor settings panel                    | `data-*` attributes               |
| **Styling**                          | Editor pickers (colours, spacing, fonts) | `--dkl-*` CSS styling tokens      |
| **Which discount**                   | The block's **Discount** picker          | `data-discount-id` attribute      |
| **Product cards / collection grids** | ✅ Supported                              | ❌ Product-page only               |
| **Needs the app embed**              | ✅ Yes                                    | ✅ Yes                             |
| **No-flicker render**                | ✅ Inline server render                   | ✅ From a head carrier             |
| **Best for**                         | Merchants, no code                       | Developers, full control          |

<Note>
  Both paths require the **Discount Kit Live** app embed to be enabled — it loads the shared
  runtime (styles + behaviour) and pre-renders the data each component reads. See
  [Enable the Global App Embed](/components/overview#enable-the-‘discount-kit-live’-app-embed).
</Note>

## App blocks

An app block is a theme block you add in the editor — **DK: Price**, **DK: Volume Groups**,
**DK: Discount Badge**, or **DK: Order Goal**. Drop it into a section or product-card slot,
and configure it entirely through the editor's settings panel.

```text theme={null}
Online Store → Themes → Customize → (add block) → DK: Price
```

What an app block does for you:

* **Resolves the eligible discount itself** — using the shared eligibility rules, so it
  agrees with the custom-tag path. When more than one discount applies, it renders the
  first eligible one, or a specific one chosen in its **Discount** picker setting.
* **Exposes every option as an editor control** — colours, spacing, labels, and
  behaviour toggles. Your choices are written into a scoped `<style>` rule the block emits,
  so styling lives in the theme editor.
* **Only loads when it's on the page** — its stylesheet and controller load with the block.
* **Reaches contexts a tag can't** — most importantly **product cards** in a collection
  grid, where there's no single product in `<head>` context to pre-stage a carrier from.

Use an app block when a merchant should be able to place and style the component without
touching code, or whenever you need it inside a product card.

## Web Components

A web component is the `<dkl-*>` web component written straight into your theme's
markup:

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

By default, a web component needs **zero attributes** — the page's primary product is the
implicit default, and the tag clones a pre-staged carrier (markup, styling, and `data-*`
values) before first paint. Configure it with `data-*` attributes and style it with
`--dkl-*` CSS:

```html theme={null}
<dkl-price
  data-show-savings="true"
  style="--dkl-price-savings-background:#111; --dkl-price-savings-color:#fff"
></dkl-price>
```

What to know about web components:

* **Product-page only.** Carriers exist only where there's a single product (or the shop)
  in context. A collection grid is paginated and per-product, so a hand-typed tag can't be
  pre-staged there — use the app block for product cards.
* **Target a specific discount** with `data-discount-id` (the metaobject handle; the
  `discount-` prefix is optional). Place one tag per discount to show several.
* **Style with `--dkl-*` tokens** in your own CSS — a tag has no block context, so there's
  no editor panel. Set the tokens on `:root`, the embed's Custom CSS, an inline `style`, or
  any ancestor. The defaults match the app block exactly, so an unstyled tag looks identical
  to a default block.
* **Behaviour toggles may default off.** For the volume picker, native-price update and
  quantity sync only run if you opt in (`data-update-price-on-change="true"` /
  `data-sync-with-quantity="true"`); any attribute you set wins over the carrier's.

Use a web component when you're editing the theme directly and want precise control over
placement, attributes, and CSS.

## Which should I use?

<CardGroup cols={2}>
  <Card title="Reach for an app block" icon="puzzle-piece">
    The merchant should configure it without code · you need it in a **product card** ·
    you want styling managed from the theme editor.
  </Card>

  <Card title="Reach for a web component" icon="code">
    You're editing theme Liquid directly · you want exact control over placement and
    `data-*` · you're styling with `--dkl-*` CSS · you need several discounts placed by hand.
  </Card>
</CardGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Overview" icon="circle-info" href="/components/overview">
    Enabling the runtime and theming with `--dkl-*` tokens.
  </Card>

  <Card title="Discount Price" icon="tag" href="/components/price/overview">
    See both placement paths on a real component.
  </Card>
</CardGroup>
