It's easy to know if a product has a valid Sale applied to it with product.defaultVariant.onSale - but how do you know which Sales are being applied to the product? How do you output that the product is currently part of a specific named sale, and any associated content you might want to show?

2 Answers 2


The real answer is:

{% for sale in variant.sales %}

    {% sale.description %}

{% endfor %}
  • Thanks Luke; that's not something I could find in the docs for either the product or sale documentation pages. I tried to check again just but the Commerce site has been offline all day. Commented Feb 23, 2018 at 14:44
  • @MattWilcox I have updated the docs. Thanks. Commented Feb 26, 2018 at 4:17
  • 1
    @LukeHolder how does this work in Commerce 3, I get: Calling unknown method: craft\commerce\elements\Variant::salesApplied()
    – Green17
    Commented May 20, 2021 at 12:46
  • 1
    @Green17 It would be for sale in variant.sales Commented May 27, 2021 at 8:00
  • This shows ALL sales that are applied. Some sales override previous sales, and these sales are still displayed. Is there a possibility to only see the sales that are really applied?
    – outline4
    Commented Nov 16, 2021 at 11:44

Thanks to Mike Pepper on the Slack chat, this is the answer. A bit disappointing that we need to go through hoops like this, but it works.

{% set productSales = [] %}
{% set allSales     = craft.commerce.getSales() %}

{% for sale in allSales if product.id in sale.productIds or product.typeId in sale.productTypeIds %}
    {% set productSales = productSales|merge([sale]) %}
{% endfor %}

{% for sale in productSales if product.defaultVariant.onSale %}
    <div class="sale">
        <p><b>{{ sale.name }}</b> - {{ sale.description }}</p>
{% endfor %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.