Listing All Products on Sale

A common need for an online store is to list all products that are on sale.

A Craft Commerce sale affects the pricing of a product’s variants. To list products on sale, we can use an element query to find all products having variants that are on sale:

{% set saleProducts = craft.products()
  .hasVariant({
    hasSales: true
}).all() %}

This product query uses the hasVariant() query parameter to further limit results by a variant query. That query sets hasSales to true to only return products having variants that are on sale.

A equivalent GraphQL query looks like this:

{
  saleProducts: products(hasVariant: {hasSales: true}) {
    title
    url
  }
}

We could then list those in one place by looping through them:

<h2>Products on Sale</h2>

{% for product in saleProducts %}
  <a href="{{ product.url }}">
    <h3>{{ product.title }}</h3>
  </a>
{% endfor %}

This is a simple example, but you could further tailor your query using product and/or variant query parameters to get a list of exactly the products you need.

For example, you might also want to list products on sale that are in stock. You could include the hasStock property in the variant query to achieve this:

{% set saleProducts = craft.products()
  .hasVariant({
    hasSales: true,
    hasStock: true
}).all() %}
{
  saleProducts: products(hasVariant: {hasSales: true, hasStock: true}) {
    title
    url
  }
}

Further Reading #

Applies to Craft CMS 3 and Craft Commerce 3.