> For the complete documentation index, see [llms.txt](https://docs.uichemy.com/llms.txt).
> Use it to discover all available pages before exploring further.

# WooCommerce Product Data

Use UiChemy's WooCommerce dynamic tags and the product Twig provider to build custom product pages, product cards, and shop templates.


UiChemy adds a full set of WooCommerce dynamic tags for binding product data to Elementor widget controls without code, plus a `product` Twig provider for outputting any product field directly in a Composer widget's HTML.

<Callout kind="info">
WooCommerce integration requires WooCommerce to be installed and active, plus **UiChemy Pro**. The `product` Twig provider and WooCommerce dynamic tags are only available when WooCommerce is active.
</Callout>

### WooCommerce Dynamic Tags

Dynamic tags let you bind product data to any Elementor widget control that supports dynamic content, no code needed. In the Elementor panel, look for the dynamic tag icon on a field, click it, and choose from the WooCommerce group.

**Text tags:**

| Tag | What it outputs |
|---|---|
| Product Title | Product name |
| Product ID | Numeric product ID |
| Product SKU | Product SKU string |
| Product Price | Formatted price HTML (auto, regular, or sale) |
| Stock Status | "In stock", "Out of stock", or "On backorder" |
| Stock Quantity | Number of items in stock |
| Product Type | simple, variable, grouped, external |
| Average Rating | Numeric rating (e.g. 4.5) |
| Sale Badge | Outputs the sale text (default: "Sale!") only if the product is on sale |
| Short Description | Product short description (HTML) |
| Description | Product full description (HTML) |
| Product Categories | Comma-separated category list with links |
| Product Tags | Comma-separated tag list with links |
| Product Attribute | Value of a specific product attribute |
| Purchase Note | Purchase note text |
| Product Slug | URL slug |

**URL tags:**

| Tag | What it outputs |
|---|---|
| Product URL | Permalink to the product page |
| Add to Cart URL | Direct add-to-cart URL (variable products redirect to the product page) |
| Checkout URL | WooCommerce checkout page URL |
| Back to Shop URL | WooCommerce shop page URL |

**Image tags:**

| Tag | What it outputs |
|---|---|
| Product Featured Image | Product featured image |
| Product Gallery Image | A specific image from the product gallery by index (0 = first) |

### The `product` Twig Provider

Inside a Composer widget's HTML panel, the `product` provider gives you direct access to every field of the current product:

```html
<article class="product-card">
  <div class="product-image">
    <img
      src="{{ product.thumbnail.src('woocommerce_thumbnail') }}"
      alt="{{ product.thumbnail.alt }}"
    >
    {% if product.is_on_sale %}
      <span class="sale-badge">Sale</span>
    {% endif %}
  </div>

  <div class="product-body">
    <h2 class="text-heading-h3">{{ product.title }}</h2>
    <p class="product-cats">{{ product.categories.name }}</p>
    <div class="product-price">{{ product.price|raw }}</div>

    {% if product.is_in_stock %}
      <a href="{{ product.add_to_cart_url }}" class="btn-primary">Add to Cart</a>
    {% else %}
      <span class="out-of-stock">Out of Stock</span>
    {% endif %}
  </div>
</article>
```

**All `product` fields:**

| Expression | Output |
|---|---|
| `product.title` | Product name |
| `product.id` | Numeric ID |
| `product.slug` | URL slug |
| `product.link` | Permalink |
| `product.price` | Formatted price HTML, use `\|raw` |
| `product.regular_price` | Regular price (raw number) |
| `product.sale_price` | Sale price (raw number) |
| `product.is_on_sale` | Boolean |
| `product.sku` | SKU string |
| `product.stock_status` | instock, outofstock, onbackorder |
| `product.stock_quantity` | Integer or empty |
| `product.is_in_stock` | Boolean |
| `product.add_to_cart_url` | Add-to-cart URL |
| `product.average_rating` | Number (e.g. 4.5) |
| `product.review_count` | Integer |
| `product.short_description` | Short description HTML, use `\|raw` |
| `product.description` | Full description HTML, use `\|raw` |
| `product.thumbnail.src` | Featured image URL (full size) |
| `product.thumbnail.src('medium')` | Featured image at a specific size |
| `product.thumbnail.alt` | Featured image alt text |
| `product.meta('key')` | Custom field / product meta value |
| `product.currency` / `product.currency_symbol` | Store currency code and symbol |
| `product.sale_percentage` | Discount percentage while on sale |
| `product.is_featured` / `is_downloadable` / `is_virtual` | Boolean product flags |
| `product.total_sales` | Number of units sold |
| `product.categories` / `product.tags` / `product.brand` | Taxonomy terms assigned to the product |
| `product.attribute('name')` / `product.attributes` | A specific attribute value, or all of them |
| `product.weight` / `dimensions` | Shipping weight and dimensions |
| `product.related()` / `upsells` / `cross_sells` | Related product collections |
| `product.variations` | Variation data for variable products |
| `product.gallery` | The product's image gallery |

<Callout kind="tip">
This list covers the most commonly used fields. The `product` provider exposes considerably more of WooCommerce's product data than fits here, if a field exists on a WooCommerce product, there's usually a matching `product.*` expression for it.
</Callout>

### Building a Product Listing With Loops

Use `get_products()` in a `{% for %}` loop to build a dynamic product grid:

```twig
<div class="uc-grid-3">
  {% for product in get_products({
    posts_per_page: 9,
    orderby: 'date',
    order: 'DESC'
  }) %}
    <article class="uc-blog-card product-card">
      <a href="{{ product.link }}">
        <img
          src="{{ product.thumbnail.src('woocommerce_thumbnail') }}"
          alt="{{ product.thumbnail.alt }}"
        >
      </a>
      <div class="card-body">
        {% if product.is_on_sale %}
          <span class="text-label" style="color: var(--color-brand)">Sale</span>
        {% endif %}
        <h3 class="text-heading-h4">{{ product.title }}</h3>
        <div class="product-price">{{ product.price|raw }}</div>
        <a href="{{ product.add_to_cart_url }}" class="btn">Add to Cart</a>
      </div>
    </article>
  {% endfor %}
</div>
```

Filter by category:

```twig
{% for product in get_products({
  posts_per_page: 6,
  tax_query: [{
    taxonomy: 'product_cat',
    field: 'slug',
    terms: ['featured']
  }]
}) %}
```

Filter to featured and in-stock only:

```twig
{% for product in get_products({
  posts_per_page: 8,
  meta_key: '_featured',
  meta_value: 'yes',
  meta_query: [{
    key: '_stock_status',
    value: 'instock'
  }]
}) %}
```

### Theme Builder and WooCommerce

When building [WooCommerce Theme Builder templates](/uichemy-plugin/theme-builder/woocommerce-templates), Single Product and Products Archive, the `product` Twig provider automatically resolves to the correct product in context:

- On a Single Product template: `product` is that product.
- Inside a product loop (`get_products`): `product` is the loop variable.
- On a Products Archive template: `product` resolves per item in loop context.

<Callout kind="info">
Cart and checkout pages aren't Theme Builder template types, they render WooCommerce's own output. The `product` provider and dynamic tags above are for product and shop *display*; use the Checkout URL and Add to Cart URL tags to link to those pages.
</Callout>

### Frequently Asked Questions

<ExpandableGroup>
  <Expandable title="product.price|raw outputs HTML, can I strip the tags?" default-open="false">
    Use `{{ product.price|raw|striptags }}` to get the plain text price without the currency symbol markup. If you only want the numeric value, use `{{ product.regular_price }}` or `{{ product.sale_price }}`.
  </Expandable>

  <Expandable title="How do I show a star rating?" default-open="false">
    Output `{{ product.average_rating }}` and build the star display in HTML/CSS. Use `{% for i in range(1, 5) %}` to render star icons and compare against the rating value.
  </Expandable>

  <Expandable title="Can I link to the WooCommerce cart or checkout?" default-open="false">
    Yes, use the **Checkout URL** dynamic tag, or hardcode your checkout page path since WooCommerce page URLs are stable.
  </Expandable>
</ExpandableGroup>

### Related

<Columns cols={2}>
  <Card title="Dynamic Content Overview" href="/uichemy-composer/design-data/overview">
    See how WooCommerce data fits among the other data options.
  </Card>
  <Card title="Twig" href="/uichemy-composer/design-data/twig">
    See the full expression syntax product data is built on.
  </Card>
  <Card title="Loops" href="/uichemy-composer/design-data/loops">
    Build a product grid with `get_products`.
  </Card>
  <Card title="Dynamic Tags" href="/uichemy-composer/design-data/dynamic-tags">
    Bind a single product field with no code.
  </Card>
  <Card title="WooCommerce Theme Builder Templates" href="/uichemy-plugin/theme-builder/woocommerce-templates">
    See product data powering a real WooCommerce template.
  </Card>
</Columns>
