Sale on products that already have a compare-at price
Your variants already show a struck-through price. What should the 'was' price be during a sale, what Shopify's collection grid does, and how SafeSale handles it.
By Beacon Wave Studio · · 7 min read
A good share of catalogues already have a compare-at price on every variant before any sale starts. Sometimes it is a manufacturer's list price the brand sells under all year. Sometimes it is left over from a sale in March that nobody fully reverted. Either way, the question lands in our inbox every October in the same words: we want to run 20% off, the products already show a “was” price, what happens to it?
Shopify's answer is that nothing happens unless you make it happen. This post covers what the compare-at field actually is, the two defensible choices for what a shopper should see during the sale, the collection-page quirk that catches most stores, and exactly what SafeSale writes, warns about and restores when a variant already has a compare-at.
What compare-at is, and is not
Shopify's help page on setting sale prices describes the mechanism in one sentence: set the compare-at price to the original price, make sure it is higher than the price, and the theme shows both with a sale badge. That is the whole feature. There is no history behind the field, no date, no link to the sale that set it. It is a number next to another number, and the theme draws a line through the bigger one.
So when a product already carries a compare-at of 100 and sells at 80, Shopify has no idea whether the 100 is a list price you intend to keep showing forever or the ghost of an old promotion. A sale that lowers the price to 64 and leaves the 100 alone will display “was 100, now 64”, a 36% saving, when what you decided on was 20%. The arithmetic is right by Shopify's rules and wrong by yours.
Two honest answers, and the one SafeSale picks
There are two things the struck-through figure could reasonably mean during a sale.
- The price yesterday. “Was 80, now 64.” The saving shown is the saving you are actually giving this week, measured against what shoppers would have paid before the sale.
- The list price. “Was 100, now 64.” The figure is the manufacturer's suggested price and the saving includes your everyday discount as well as the sale.
SafeSale's price-rewrite mode takes the first view. When a sale starts, each variant's compare-at is set to the price the variant had the moment before, and the price drops to the sale figure. When the sale is reverted, both fields go back to exactly what they were, including the 100 that was there all along. The pre-sale values live in the snapshot that we described in the snapshots post, and the snapshot stores the compare-at as well as the price for precisely this reason.
We chose that behaviour because it is the one regulators and shoppers agree on. A reference price is supposed to be a price the product was genuinely sold at recently. The UK's CMA has pursued mattress brands over “was” prices that were never really charged, a story we covered in the countdown-timers post, and EU price-indication rules ask that an announced reduction be measured against the lowest price applied in the 30 days before. A compare-at that equals last week's selling price passes both tests without anyone having to think about it on launch morning.
What the preview tells you before anything changes
Because the compare-at decision is one a merchant might disagree with, SafeSale does not make it silently. The preview you see before a sale goes live flags every variant where an existing compare-at will be replaced, in two flavours.
- Existing compare-at will show as [price] during the sale and be restored afterwards. The common case: a list price higher than the selling price. It is set aside for the sale and comes back on revert.
- Existing compare-at is lower than the price; it will be replaced by [price] during the sale. The odd case: a compare-at of 70 on a variant selling at 80, usually a data-entry slip or a price rise that forgot the second field. Themes ignore a compare-at that is lower than the price, so nobody noticed. The warning is there so you can fix the source data rather than carry the mistake through a sale.
The preview sits alongside the other checks we described in the double-discount post, where a variant that is already in another SafeSale sale is blocked rather than discounted twice. Read the warnings, and if the list-price view is what you want for a particular range, that is a reason to run that range in the other mode, below.
The collection page problem
Here is the quirk that generates the most “the sale badge is missing” tickets. The same Shopify help page explains that a collection grid shows a product as on sale only when the compare-at pricing is consistent across all of its variants. If one size has a compare-at of 100, another has 0.00 and a third is blank, the product page shows each variant correctly because it is looking at one variant at a time, but the collection tile shows the product at full price.
Catalogues that already have compare-at prices are the ones most likely to be in this state, because the values were typed in by hand or imported from a supplier file over several years. A sale that only touches the variants that matched a rule can make it worse: now some variants have “was 80” and the untouched ones still have “was 100” or nothing.
SafeSale writes price and compare-at together for every variant the sale includes, so within a sale the pairs are consistent by construction. What it cannot do is invent values for variants you left out of the sale. If a product has eight variants and your rule only selects four, the tile may still disagree with the page. The practical advice is to build sales at product level when you want the badge in the grid, and to tidy stray compare-at values before the season starts rather than during it.
When you would rather keep the list price visible
Some brands sell under MSRP as a positioning choice and want the 100 on the page at all times. For them, replacing it with 80 for a week reads as losing a selling point. The fix is to not touch the fields at all. SafeSale's Functions mode creates an automatic discount for the sale instead of rewriting prices, so price and compare-at stay exactly as they were and the 20% comes off in the cart and at checkout. The product page keeps showing your MSRP comparison, and the sale is a discount line rather than a struck-through figure.
The two mechanisms are compared properly in our automatic-discounts-versus-rewrites post. For the compare-at question specifically the summary is short: rewrite when you want “was 80, now 64” on the product page, discount when you want “100” to stay put and the saving to appear later. Both can run at once on different collections.
What happens if a variant is already where the sale wants it
One more detail for stores with history. Before SafeSale writes a variant, it reads the live price and compare-at. If they already equal the sale's target, because someone hand-edited the product last week or a previous attempt half-applied, the variant is marked as applied without a write. Nothing is changed that did not need changing, and the snapshot still records what was there before the sale so revert has something to go back to.
A short checklist before a sale on an already-discounted catalogue
- Export your products and sort by compare-at. Fix blanks, zeros and values lower than the price now, while nothing is live.
- Decide per range whether the “was” price should be last week's price (rewrite) or the list price (automatic discount).
- Build rewrite sales at product level so every variant of a product is written together and the collection grid agrees with the page.
- Open the preview and read the compare-at warnings. Anything you did not expect is cheaper to fix before launch.
- After the sale, confirm the revert restored the original compare-at values, and keep the sale's log in case a customer asks what the price was.
A compare-at price that already exists is not an obstacle to a sale, just a decision that has to be made on purpose. SafeSale makes it visibly, in the preview, and puts everything back when the sale ends.
Frequently asked questions
What happens to an existing compare-at price when I run a sale in Shopify?
Nothing automatic. Shopify's compare-at field is a number you set; it has no memory and no rule for sales. If you lower the price and leave the old compare-at in place, the storefront shows a bigger saving than you actually offered this week, and when the sale ends you have to remember what both fields were.
Should the 'was' price during a sale be the MSRP or the price I was actually charging?
The price you were charging. A shopper reads a struck-through figure as the price they would have paid yesterday. If a variant listed at 100 with an 80 selling price goes on sale at 64, SafeSale shows 'was 80, now 64' and puts the 100 back when the sale is reverted. Consumer-pricing rules in the UK and EU take the same view of reference prices.
Why does the sale badge show on the product page but not in the collection?
Shopify's collection grid only shows a product as on sale when every variant's compare-at pricing is consistent. If some variants have a compare-at and others have none, or the values disagree, the grid shows the product at full price while the product page shows the variant correctly. A sale that writes compare-at on every variant of the product fixes this; one that touches a subset does not.
Can I keep the MSRP visible and still run a sale?
Yes, by using an automatic discount instead of a price rewrite. SafeSale's Functions mode leaves price and compare-at exactly as they are and applies the reduction in the cart and checkout. The product page then shows your usual MSRP comparison and the sale appears as a discount line. You lose the struck-through sale price on the product page, which is the trade.