Shopify Compare at Price Not Showing? Check the Data
The crossed-out price is usually missing because the value was never saved, not because the theme is broken. Check it in one request, then fill it in for every variant at once.
By AjayCodeWiz · July 27, 2026 · 9 min read
The problem
A merchant posted on the Shopify Community that the compare-at price on their store was not showing. They had already done a lot of work on it.
They had confirmed the Liquid in main-product.liquid was correct. They had confirmed the .old-price CSS rule existed in the stylesheet. They had been told the compare-at price was set to 420 euros on every variant. Their theme was Xclusive 3.2.0, a custom theme uploaded manually rather than installed from the Theme Store.
Three people replied, and all three sent them further into the theme code: check the price snippet, check whether the product template uses a different component, inspect the element to see whether CSS is hiding it.
All reasonable advice. All aimed at the wrong layer.
I checked their live store before suggesting anything, and the compare-at price was not there to display. The data was missing.
Check the data first, it takes one request
Every Shopify product has a public JSON endpoint. Add .js to any product URL and you get the raw product data the storefront is working with:
https://yourstore.com/products/your-product-handle.jsOn their store, that returned:
"compare_at_price": null,
"compare_at_price_min": 0,
"compare_at_price_max": 0null. Not a rendering problem, not a CSS problem, not a theme problem. There was no compare-at price saved on any variant of any product.
Do this check before you touch a single theme file. If compare_at_price is null, no amount of Liquid will make a crossed-out price appear, because there is nothing to cross out.
You can check every product at once:
curl -s https://yourstore.com/products.json?limit=250 \
| grep -o '"compare_at_price":[^,]*' | sort | uniq -cThat prints a count of how many variants have a value and how many are null. If the null count is everything, stop reading the theme and go fill in the data.
Here is the same product before and after, on my test store. Nothing changed except the price data.
Before and after: only the price data changed
What compare-at price actually is
Compare-at price is the "was" number. It is the higher, crossed-out price shown next to the current selling price to signal a discount.
Two rules govern whether it renders, and both catch people out.
It lives on the variant, not the product. This is the big one. If your product has sizes 36 through 46, that is eleven variants, and each one carries its own compare-at price field. Filling in the first variant does nothing for the other ten. A product page will show the crossed-out price for size 38 and not for size 39, which looks like a random theme bug and is not.
It must be higher than the selling price. If compare-at equals the price, or is lower, every well-built theme renders nothing at all. This is deliberate: a strikethrough showing the same number is noise, and a strikethrough showing a lower number is a lie. So setting compare-at to 420 and the price to 420 produces exactly the symptom in this thread, an invisible compare-at price on a product that definitely has one saved.
Worth knowing: the second rule means a compare_at_price that is present but not greater than price is functionally the same as null. When you run the check above, look at the values, not just whether they exist.
The fix: fill it in for every variant at once
Doing this one variant at a time is what makes people give up and go looking for a theme bug instead. Use the bulk editor.
Step 1: select the products and open Bulk edit
Go to Products in your admin. Tick the products you want to price, then click Bulk edit in the bar that appears.
Select the products, then Bulk edit
The bulk editor opens as a spreadsheet, one row per variant. That row-per-variant behaviour is exactly what you want here, because it is the reason the manual approach is so slow.
Step 2: add the Compare at price column
The column is not shown by default. Click Columns, search for "compare", and tick Compare at price.
Columns, search compare, tick Compare-at price
While you are in there, it is worth adding the Price column too if it is not showing, so you can see both numbers side by side and confirm compare-at is the higher one.
Step 3: type the old price and save
Fill in the Compare at price column, then Save.
Type the old price in the Compare-at price column, then Save
You can type a value in the first cell and paste it down the column, the same as any spreadsheet. Every variant of every selected product gets its value in one pass.
Reload the storefront. The crossed-out price appears, and so does whatever sale badge your theme draws from the same data.
Doing it at scale, or on a schedule
The bulk editor is right for a few hundred variants. Past that, or if you want this to be repeatable, there are two better routes.
CSV export and import. Go to Products, Export, and open the CSV. The column is Variant Compare At Price. Fill it in, import the file back. This is the fastest route for thousands of variants and it gives you a record of what you changed.
A percentage markup with a formula. If your "was" price is a consistent markup on your current price, do it in the spreadsheet. Export, set Variant Compare At Price to = Variant Price * 1.3 for a 30 percent apparent discount, then import. Ten seconds for the whole catalog.
One caution on the second one. A compare-at price is a claim about what the item previously sold for, and in several markets, including the UK, EU and much of the US, inventing that number is a regulated pricing practice. Use a price you actually charged.
Why theme edits were the wrong instinct here
The replies in that thread were not careless. They followed a reasonable chain: the merchant says the data is set, the data is not showing, therefore the display layer is at fault.
The weak link is "the merchant says the data is set". On a custom theme, with a store built by an agency, with prices that were configured by someone else, that is exactly the assumption worth testing first. It cost one HTTP request to test and it turned out to be false.
The general form of this is worth keeping: when something is not displaying, confirm the value exists before you go looking at how it is rendered. Shopify makes that cheap, because .js on any product URL and /products.json on any store are both public and need no authentication.
That also means you can run this check on a store you do not own, which is how I checked theirs before answering.
Common questions
Compare-at price shows on the product page but not on collection pages.
Different template, different snippet. Most themes render the price through a shared price.liquid snippet, but some have a separate card price component. If the data is present and one surface shows it, that surface is now your reference: find what it calls and check the other one calls the same thing.
The strikethrough shows on the first variant only.
Classic symptom of compare-at being filled in on variant one and nowhere else. Open the bulk editor and look down the column. It is also worth checking that your theme's variant-switching JavaScript updates both prices rather than only the current price, but check the data first.
Compare-at is set and higher, and still nothing renders.
Now it is worth looking at the theme, and now you have ruled out the common cause. Inspect the element on the price area. If the markup for the old price is in the DOM but invisible, it is CSS. If the markup is not in the DOM at all, the price snippet your template actually uses does not have the compare-at logic in it.
Does compare-at price affect anything besides the strikethrough?
Yes, and this is worth knowing. Sale badges, "on sale" collection filters, and the sale sorting option all key off compare-at being higher than price. Filling it in switches on several theme features at once, which is often a pleasant surprise.
Can I set compare-at without putting the product on sale?
No, and that is the point of the field. If compare-at is higher than the price, Shopify considers the variant on sale, and any theme feature that keys off that will treat it as such.
If it did not work
Run the JSON check again after saving. If compare_at_price is still null, the save did not land, usually because the bulk editor had a validation error on another column that blocked the whole save.
If the value is there and higher than the price and still nothing shows, share your theme's price snippet. At that point it genuinely is a theme problem, and you have eliminated the cause that accounts for most of these threads.
Tested on
I reproduced this on a Shopify dev store: set a compare-at price through the bulk editor across multiple variants, confirmed it rendered, then cleared it and confirmed the strikethrough disappeared while the theme code stayed untouched. The store in the original thread was checked read-only through its public product JSON.
Fixing product data one row at a time?
PinFlow reads your Shopify catalog automatically and turns it into Pinterest pins on a schedule. Set the data once, let the automation use it everywhere.
Get PinFlow on the Shopify App StoreMore Shopify fixes
More community-sourced Shopify guides, tested on a live store.
Collections & Products
How to Add Variant Images in Shopify So Photos Switch
If clicking a colour does not change the product photo, that colour has no variant image attached. How to add variant images in Shopify, and why a swatch is not the same thing. Tested on Dawn 15.
Collections & Products
Shopify Category Grid: Add More Than 8 Tiles in Dawn
Shopify's collection grid seems capped at 8 tiles, and stacking two sections leaves a gap. Here is how to get a seamless 16-tile category grid on a free theme with one number change.
Collections & Products
Shopify Variant Limit: 2,048 Variants and 3 Options
Shopify raised the variant cap to 2,048 in October 2025, but the three-option limit never moved. Here is which one actually blocks you, and how to price by size and quantity without an app.