How does one get the sale price of a product in Craft Commerce on a product page? I'm new to Craft and Twig and the sale section of the Commerce docs is.. well, not really there (page under construction). I have a product that has a sale set on it. I pull the single product without problem:

{% set product = craft.commerce.products({
    relatedTo: category,
    slug: craft.request.getSegment(3),
    status: 'live',
}).first() %}

Product Title - {{ product.title }}
Product Price - {{ product.defaultPrice|commerceCurrency(cart.currency) }}

But a {{ dump(product) }} doesn't show any discount or sale values at all. I know the sale exists and is up; this returns my sale name:

{% for sale in craft.commerce.sales %}
    {{ sale.name }}
{% endfor %}

And I know my product is a part of that sale, it shows it as a related sale on the product entry page. The sale is wide open (no expiry or start, just one product picked (the one that populates the page I'm testing)). All attempts at sales price result in a templating error: {{ product.price }},{{ product.salePrice }},etc.

The only thing I can think is a nested loop and then conditionals... something like (pseudo code):

<span class="price">
{% for sale in sales %}
    {% for sale_product in sale.products %}
        {% if sale_product.sku == product.sku %}
            ... do some weird math?
            Check if % off or $ off and math it up with
            {{ product.defaultPrice }}?
        {% endif %}
    {% endfor %}
{% endfor %}

And that is clearly not how this is supposed to be done. Thanks!


And for that matter, how do I check if it is on sale at all, regardless of the sale value? The client design involves slightly different coloring/styles for a sale price versus a default price.

2 Answers 2


I think you would probably also need to check the default variant of the product, e.g.:

{% if product.defaultVariant.onSale %}
  {% set price = product.defaultVariant.salePrice %}
{% else %}
  {% set price = product.defaultVariant.price %}
{% endif %}

Product Price - {{ product.price }}

I believe you can always simply use product.defaultVariant.salePrice as this will be set to equal product.defaultVariant.price if there is no sale applied.

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.