Filed under Auto Markdown

Shopify Compare-At Price: The Complete Operator’s Guide

What Shopify's compare-at price is, every way to set or remove it, why it fails to show, and what it does to discounts, reports, Google feeds and the law.

Shopify Compare-At Price: The Complete Operator’s Guide

The Shopify compare at price is the second price field on every variant. Put the product’s original price in it, put a lower number in Price, and your theme shows the original struck through next to the sale price. That is the entire mechanism, and Shopify’s own instruction for it is one sentence long: “Make sure that the value in the Compare-at price field is higher than the value in the Price field to display the sale price” (Shopify Help Center, Setting sale prices for products).

Almost everything that goes wrong comes from the distance between how simple the field is and how many systems read it. Your theme reads it to draw a strikethrough and a badge. Automated collections read it. Shopify Markets converts it, overrides it, or hides it. Google checks it against your landing page. Regulators in the US and the EU have rules about what the number may be. None of those systems will tell you when the value is stale.

We build Auto Markdown, a Shopify app that writes to this field and clears it again, so we have spent a lot of time on what happens after the value is saved. This guide covers what the field means, every way to add, change, or remove it, why it fails to display, and what it does to discounts, reports, shopping feeds, and your legal exposure. Where Shopify’s documentation is silent or contradicts itself, we say so and link the page.

Key takeaways

  • A compare-at price only displays when it is higher than Price. Equal, lower, or $0.00 values produce no strikethrough, and Shopify states that “a compare-at price of $0.00 USD isn’t the same as an empty compare-at price.”
  • The field lives on the variant, not the product. Inconsistent values across variants are the documented reason a sale shows on the product page but not on the collection page.
  • A compare-at sale is not a discount in Shopify’s reports: “Discounts are created using discount codes, not the compare-at price,” so markdown cost never appears in the Discounts column.
  • Google only shows a sale price annotation when the discount is greater than 5% and less than 90%, and in most cases only when the base price has a track record.
  • The bulk editor and CSV import change values when you click. Reverting is a second manual job unless an app holds the original price.

Compare at price meaning: what the field actually is

Shopify’s product data has two customer-facing price fields per variant. Price is what the customer pays. Compare-at price is a reference number displayed for comparison, and Shopify’s help page describes its intended content plainly: you “set the value of the Compare-at price field in your Shopify admin to the original price of the product.” Nothing is charged from it, and nothing is calculated from it at checkout.

The same page draws the line that the rest of this guide depends on: “Using sale prices is different from setting up discounts. If you set a sale price and a compare-at price, then both these amounts can be displayed on product pages and collection pages, but only the sale price is displayed at checkout.” A compare-at sale is a change to catalog data. A discount is a calculation in the cart. They are separate machinery that happen to produce a similar-looking result.

What the field does not do

Three things the field is easy to assume it does, and does not:

  • It does not lower the price. Adding a compare-at value above an unchanged Price creates a strikethrough with no actual reduction. The sale only exists if you also lowered Price.
  • It does not remember anything. Shopify’s page on the EU pricing rules notes that “the product details in your Shopify admin have only two fields for product price: the price, and compare-at price” (Shopify Help Center, European Price Indication Directive). There is no third field holding the pre-sale price. If you overwrite Price without recording the old value somewhere, the compare-at field is the only copy of it.
  • It does not expire. The field has no start or end date. We covered the scheduling gap, and every workaround for it, in our guide to scheduling a sale on Shopify, so this post will not repeat it.

Variant-level, not product-level

There is no product-level compare-at price in the data. Each variant carries its own, and what themes call the product’s compare-at price is derived. Shopify’s Liquid reference defines product.compare_at_price as “the lowest compare at price of any variants of the product,” with compare_at_price_max for the highest and compare_at_price_varies returning true when the variant values differ (shopify.dev, Liquid product object). The variant object has its own compare_at_price, output “in the customer’s local (presentment) currency” (shopify.dev, Liquid variant object).

A product page usually renders the selected variant, so it reads that variant’s two fields. A collection card has no selected variant, so it reads the derived product-level numbers. Two surfaces, two different inputs — which is why a sale can be correct on one and absent on the other.

How to add, change, or remove a Shopify compare at price: every method

The routes to the field differ in scale and in one property most tutorials skip: what happens at the end of the sale.

MethodBest forScaleReverts automatically?
Product page in the adminOne product, or a quick correctionOne product at a timeNo
Variant editing inside a productPutting every size or colour of one product on sale consistentlyAll variants of one productNo
Admin bulk editorA collection-sized sale with hand-entered pricesDozens of products comfortably (our judgment, not a documented limit)No
CSV export and importPercentage-based sales across a large catalog, using spreadsheet formulasHundreds to thousands of variantsNo — the untouched export is your revert file
Markets catalogs and market CSV columnsDifferent compare-at prices per country or regionPer marketNo
Bulk-edit and sale-scheduler appsCatalog-wide sales with a start and end timeDepends on the app and planDepends on the app — confirm on its listing before you rely on it
Auto Markdown (our app)Slow-selling products marked down by rule, not by calendar50 tracked products on the free plan up to unlimited on EnterpriseYes — restores the original price after the product sells

Add a compare at price on a single product

Shopify documents the steps on both the sale pricing page and the Price Indication Directive page:

  1. From your Shopify admin, go to Products and click the product.
  2. In the Price section, click Compare at.
  3. In the Compare-at price field, enter the original price.
  4. In the Price field, enter the new, lower price.
  5. Click Save.

Copy the current price into Compare-at before you type over Price, because once Price is overwritten and saved, the admin has no record of what it used to be. To change a compare-at price, edit the same field. To remove one, clear the field completely — do not type 0.

Compare at price for variants, and for all variants at once

For a product with variants, the two fields sit on each variant. Shopify’s sale pricing page points to bulk editing multiple variants as the way to set them together, and the general bulk editor handles it the same way as any other property: you add the Price and Compare-at price columns and edit the cells (Shopify Help Center, Bulk editing).

The rule we apply without exception: when one variant of a product goes on sale, decide what every other variant’s compare-at field should contain, and set it deliberately. Either all variants get a compare-at price higher than their own price, or the variants not on sale have a genuinely empty field. Half-filled products are the cause Shopify itself documents for missing strikethroughs on collection pages.

Compare at price bulk edit in the admin

The documented flow is short: go to Products, tick the checkboxes for the products you want, and click Bulk edit. Click Columns and add Price and Compare-at price if they are not showing. Then, in Shopify’s words, “click and then type in a field in the table to enter or edit the property for that list item,” and click Save.

You can also “click and drag the cell’s fill handle across the cells below or above” to copy one value down a column, which helps when a whole collection shares one original price.

Shopify’s bulk editing documentation does not describe a formula, a percentage adjustment, or an undo; it describes typing values into cells. So a “20% off this collection” sale run through the bulk editor means calculating each sale price yourself. That is the point at which a spreadsheet becomes the better tool.

CSV import: the column names

Shopify’s current product CSV format uses these headers for the fields that matter here (Shopify Help Center, Using CSV files to import and export products):

URL handle
Title
Option1 name
Option1 value
SKU
Price
Price / International
Compare-at price
Compare-at price / International
Cost per item

Shopify describes Compare-at price as “the original price of the variant if the price has been reduced and you want to display the price comparison,” entered as a number with no currency symbol. The word “International” in the market columns is a placeholder: the column is named after your market, and Shopify notes that “a fixed price for a product in a market is required to use a fixed compare-at price.”

If your spreadsheet says Handle, Variant Price, and Variant Compare At Price instead, you are looking at the older template — the one we described in our scheduling guide. Shopify’s page does not list the legacy names, but it does say: “If you use an older CSV template, then you might have different column names than the ones that are listed on this page. Shopify maintains backward compatibility with older column names, but you should consider updating to the current format.” The simplest way to get the current headers is to run a fresh export and edit that file.

Two documented behaviours decide whether a CSV import helps or hurts you:

  • A blank cell erases. “If a non-required column in the import CSV file is blank, then the matching value in the product list is overwritten as blank.” An import with empty Compare-at price cells removes every compare-at price it touches — what you want at the end of a sale, and a disaster in the middle of one.
  • A missing column is ignored. “If a non-required column isn’t included in the import CSV file, but is included in the existing product list, then the value in the product list remains the same.” Shopify states that when updating, “the only required columns are URL handle and Title.” So the safest price import is a narrow one: keep the identifying and option columns exactly as exported, keep the two price columns, and delete the rest.

Save an untouched copy of the export before editing anything. Re-importing it is the revert.

Markets and catalogs

If you sell internationally through Shopify Markets, each market’s catalog can carry its own pricing. When you enter a percentage price adjustment on a catalog, Shopify’s documentation says “by default, this adjustment also applies to compare-at prices. To set compare-at prices manually, toggle off the Include compare-at price setting” (Shopify Help Center, Creating catalogs for markets). The catalog CSV has its own pair of columns, Fixed Price and Compare At.

Shopify’s pages disagree with each other on whether market sale prices can be entered in the admin. The sale pricing page says fixed sale prices for international markets are created “by importing prices using a CSV file. Sale prices can’t be created within the Shopify admin.” A changelog entry dated October 27, 2025 says the opposite: “You can now set and edit compare-at prices directly in Catalogs” (Shopify Changelog). We read the changelog as the newer statement, but check your own admin rather than taking either on trust.

Apps, including ours

Apps that write to this field fall into three groups: bulk price editors, sale schedulers with a start and end time, and rule-based markdown apps that react to what is selling. We compare tools across the category in our guide to the best Shopify discount apps in 2026.

Auto Markdown is ours, and it belongs to the third group only. You set a rule — a number of days without a sale, a percentage, and a floor — and when a tracked product stalls, the app lowers Price and writes the original price into the compare-at field. Its App Store listing describes the other half: “Original prices restore automatically after a sale is made,” at which point the compare-at field is cleared. Rules can target a collection, product type, or vendor.

What it is not: a general bulk editor. It will not put a hand-picked list of products on sale from Friday 6 p.m. to Sunday midnight, it does not create discount codes, and it has no App Store reviews yet, so you are relying on our description and your own trial. If your job is “set a compare-at price on these 400 products today,” use the CSV method or a bulk editor app.

Compare at price percentage: the math, with an illustrative example

Shopify stores two amounts. It does not store a percentage. Any “25% off” label on your storefront is computed from the two fields, and the formula is always the saving divided by the compare-at price:

percent off = (compare-at price − price) ÷ compare-at price × 100
sale price  = compare-at price × (1 − percent off ÷ 100)

An illustrative example. Say a store sells a jacket at $80 and wants to mark it down 25%:

StepCalculationResult
Compare-at price (the original)—$80.00
Sale price at 25% off80 × 0.75$60.00
Saving80 − 60$20.00
Percent off (correct denominator)20 ÷ 8025%
Percent off (wrong denominator)20 ÷ 6033% — this is the increase from sale price back to original, not the discount

The wrong-denominator error shows up in both directions. A merchant who wants the badge to read 25% and divides the sale price by 0.75 to find a compare-at price is doing legitimate arithmetic only if the answer was the product’s real former price. If it was not, the arithmetic has produced a fictitious reference price, and that is a legal problem rather than a maths problem.

Rounding changes the label

Second illustrative example. A product at $49.99 marked down 15% comes to $42.4915, which you would enter as $42.49. The saving is $7.50, and 7.50 ÷ 49.99 is 15.0%. Now suppose you prefer the look of $42.99. The saving is $7.00, and 7.00 ÷ 49.99 is 14.0%. A theme that prints the percentage will now say 14% while your email says 15%. Choose the price endings first, then advertise the percentage they produce.

Variants with different depths

Say sizes S and M are $40 against a compare-at of $50 (20% off), and size L is $45 against $50 (10% off). On the product page, the label should change as the shopper switches size. On the collection card there is one label for three variants, and the theme has to choose what to show. Themes differ, so check the card whenever depth varies by variant. If it looks wrong, the cheapest fix is usually to make the depth uniform across the product.

Shopify strikethrough price, sale badge, and “% off” label: where they come from

Shopify stores the numbers; the theme decides what to draw. Shopify’s help page says only that “sale price styling on your storefront can often be customized through your theme settings” and sends you to your theme’s documentation for specifics. So the honest general answer is that every theme implements its own version of the same test.

Dawn, Shopify’s open-source reference theme, shows what that test looks like. In its price snippet, the on-sale styling is applied when compare_at_price > price (Dawn, snippets/price.liquid). Strictly greater than: equal values are not a sale. Three further details in Dawn’s source explain behaviour that can look like a bug:

  • The card badge requires stock. In the product card snippet, the sale badge renders when card_product.compare_at_price > card_product.price and card_product.available; an unavailable product gets the sold-out badge instead (Dawn, snippets/card-product.liquid). A sold-out sale item loses its sale badge by design.
  • Mixed compare-at values can hide the strikethrough. The price snippet adds a price--no-compare class when the product’s price does not vary but its compare-at price does. That is the theme-side expression of the variant-consistency rule in Shopify’s help page.
  • The badge is a word, not a number. Dawn’s badge prints a translation string, products.product.on_sale. There is no percentage calculation in the snippet. Dawn’s global settings expose the badge position, corner radius, and colour scheme — not a percentage option.

Themes that do print “Save 25%” or “−$20” compute it in Liquid from the same two fields, using the formula in the previous section. If the label is wrong, the data or the rounding is wrong; the theme is not consulting a separate discount setting. And the label will reflect whatever is in the compare-at field, including a value somebody typed by mistake eighteen months ago.

Dawn is one theme. We cite it because its source is public and maintained by Shopify, not because yours behaves identically. For a paid theme, the developer’s documentation is the authority on whether the badge can be switched off, restyled, or changed to a percentage.

Shopify compare at price not showing: the troubleshooting tree

Work through these in order: data, then theme, then market, then cache. That is the order of cost to check.

SymptomLikely causeFix
No strikethrough anywhereCompare-at price is lower than or equal to PriceMake compare-at strictly higher than Price. If the two are swapped, swap them back.
Shows on the product page, not on collection pagesVariants have conflicting compare-at values: some empty, some $0.00, some differentGive every variant a compare-at price above its own price, or clear the field on all of them
Sale product missing from your automated Sale collectionAt least one variant has an empty compare-at fieldSet a compare-at price on every variant of the product
Strikethrough shows, badge does notTheme renders badges only on certain templates, or the product is sold outCheck the theme’s card and product settings; in Dawn a sold-out product shows the sold-out badge instead
Shows at home, missing for visitors in EEA countriesCompare-at prices hidden for that marketMarkets > the market > More Settings > Compare-at price, then review the Hide compare-at setting
Shows in one market with a different amount, or not at allA fixed price in that market’s catalog overrides the base fieldsSet the fixed price and compare-at for that market, in the catalog or by CSV
Correct in the theme editor preview, wrong on the live siteYou edited an unpublished theme, or you are seeing a cached pageConfirm which theme is published; reload in a private window
Sale price missing on the product page during a discount campaignThe sale is an automatic discount or code, not a compare-at priceDiscounts apply in cart and checkout; use compare-at pricing if you need the product page to show it

1. Check the price relationship

Open the variant and read both fields. Shopify’s caution is unambiguous: “To display a sale price, the value in the Compare-at price field must be higher than the value in the Price field.” The common ways to break this are entering the numbers in the wrong fields, restoring Price after a sale while leaving the old compare-at in place, and raising Price above a compare-at value set long ago.

2. Check every variant

Shopify documents this case itself: “If your compare-at price displays correctly on product pages but doesn’t display on collection pages, then it’s likely because some variants have conflicting compare-at pricing.” A collection page “displays the most general information that applies to all variants,” so if some variants have a compare-at of $0.00, some are empty, or the values differ, “the collection page won’t display the product as being on sale, even if individual variants are.”

The documented fix is to “either remove all conflicting compare-at pricing and leave them blank, or ensure all compare-at prices are higher than their respective regular prices.” Then the sentence that tutorials recommending a zero get wrong: “A compare-at price of $0.00 USD isn’t the same as an empty compare-at price. Make sure to clear the field entirely for variants that shouldn’t display a compare-at price.”

Zero and empty also behave differently in automated collections. Shopify’s conditions documentation says “Zero (0) isn’t the same as empty,” and that the condition is evaluated across variants: “if any variant has an empty compare-at price, then the product matches the is not set condition” (Shopify Help Center, Understanding conditions for collections). So a product with one discounted variant and one empty variant will not enter a Sale collection built on “compare-at price is set.”

3. Check the theme

If the data is right and the strikethrough is missing on a specific template, the theme is the next suspect. Collection cards, featured product sections, search results, and product pages can each have their own price and badge options. If the theme has been customised, test with an unmodified copy before concluding that Shopify is at fault.

4. Check markets and currency

Markets can change compare-at behaviour in three ways. A catalog’s percentage adjustment applies to compare-at prices by default. A fixed price in a market overrides the base fields — Shopify’s sale pricing page says “fixed prices will override prices and compare-at prices set in your Shopify admin.” And for markets containing European Economic Area countries, compare-at prices can be hidden altogether.

On that last point, Shopify’s Price Indication Directive page contradicts itself. One section says that for a store whose primary market is outside the EEA, compare-at prices for EEA customers “are displayed by default”; the next section says they “are hidden by default.” We cannot tell you which sentence is current. The steps to look are the same either way: from the admin go to Markets, click the market that contains an EEA country, open More Settings, click Compare-at price, and check whether Hide compare-at is selected. If several of your markets contain EEA countries, repeat this for each one.

5. Check which theme and which page you are looking at

The least interesting cause, and a real one. A setting changed in a draft theme does not affect the published theme, and an app that renders prices with its own script can override the theme’s output. Load the live product URL in a private browser window and confirm the published theme is the one you edited before you start editing Liquid.

Shopify sale badge not showing

If the strikethrough is present and only the badge is missing, the data is fine and the question is about the theme. Check whether the theme shows badges on that template at all and whether the product is sold out (in Dawn the sold-out badge takes precedence). If there is no strikethrough either, go back to step 1: both are driven by the same comparison.

Shopify sale price not showing during a discount

If you set up an automatic discount and expected product pages to show a reduced price, nothing is broken. Shopify’s discounts FAQ defines discounts as “price reductions that are applied in a customer’s cart and at checkout, either automatically or when the customer enters a discount code,” and says that showing discount savings with strikethrough pricing on product pages requires a third-party discount app or a custom build by a Shopify Partner (Shopify Help Center, Discount codes FAQ). If the product page must show the lower price, the sale has to be a compare-at sale.

How compare-at prices interact with discount codes and automatic discounts

The two systems are separate and do not coordinate. Shopify’s sale pricing page says “only the sale price is displayed at checkout,” so the price a discount code or automatic discount works from is the sale price. The compare-at field plays no part.

The practical result is stacking. As an illustrative example, a product with a compare-at price of $80 and a Price of $56 is 30% off. A customer who enters a 20% welcome code pays $44.80, which is 44% below the original. Shopify’s discounts FAQ does not describe a setting that excludes products with a compare-at price from a discount, so the practical control is to limit each discount to specific collections and keep sale items out of them.

We worked through the margin consequences in our markdown vs coupon vs bundle framework. The short version: before any compare-at sale goes live, list every active and scheduled discount and ask what each does to a product that is already marked down. If the combined depth takes you below the number you worked out as your clearance floor price, restrict the discount before launch, not after the first order.

What compare-at pricing does to reports and collections

Shopify’s sales report documentation defines gross sales as “product price x quantity (before taxes, shipping, discounts, and sales reversals)” and adds a sentence aimed squarely at this topic: “Discounts are created using discount codes, not the compare-at price” (Shopify Help Center, Sales reports).

Read that as an accounting rule. As an illustrative example, an $80 product sold at $56 through a 30% code reports $80 of gross sales and $24 of discounts. The same product sold at $56 through a compare-at markdown reports $56 of gross sales and no discount. Net sales match; the story does not.

To know what your markdowns cost, you have to record it yourself: the original price, the sale price, the dates, and units sold in between. A pre-sale CSV export is the minimum version. It is also why markdown apps keep a log; ours retains history for 7 days on the free plan, 30 on Growth, and 90 on Pro, per its App Store listing.

Collections are the other internal system that reads the field. Shopify’s conditions page lists the operators for compare-at price: is equal to, is not equal to, is greater than, is less than, is set, and is not set. “Compare-at price is set” is the usual basis for an automatic Sale collection, and it has one weakness: it tests whether a value exists, not whether the product is cheaper than it used to be. A stale compare-at value left behind after a sale keeps a full-price product in your Sale collection. The same page’s notes on how $0.00 is treated are hard to reconcile with each other, so if you rely on zero values for anything, test on one product first.

Compare-at prices in Google Merchant Center and shopping feeds

Google’s product data has the same two-price structure under different names. The price attribute carries the full, non-sale price. The optional sale_price attribute carries what you charge during the sale. Google’s specification says: “When you submit the sale price [sale_price] attribute, continue to submit the full price of your product (the cost when it’s not on sale) by also submitting the price [price] attribute” (Google Merchant Center Help, Sale price).

So the logical translation is Shopify’s compare-at price into Google’s price, and Shopify’s Price into Google’s sale_price. But the Shopify Help Center pages we checked for the Google & YouTube channel — syncing your products and the channel requirements page — do not describe how the two Shopify fields are mapped. Whether you use Shopify’s channel or a feed app, confirm the result in Merchant Center itself by opening a sale product and checking that both attributes are populated as you expect.

What Google requires before it shows the strikethrough

Submitting a sale price does not guarantee that shoppers see one. The strikethrough and sale badge on Google are a “sale price annotation,” and Google publishes the conditions (Google Merchant Center Help, About sale price annotations):

Surface and countryDiscount sizeBase price history
Free listings — Australia, Canada, United States, JapanGreater than 5% and less than 90%None listed
Free listings — Brazil, France, Germany, India, Italy, Korea, the Netherlands, Spain, United KingdomGreater than 5% and less than 90%Base price valid for 30 days within the past 200 days
Shopping ads — United StatesGreater than 5% and less than 90%Base price charged for 5 days within the past 30 days, or 15 days within the past 200 days, whichever is met first
Shopping ads — the other listed countriesGreater than 5% and less than 90%Base price valid for 30 days within the past 200 days

In every case the sale price must be lower than the base price, and “the original price and sale price should be displayed on the landing page.” Google adds that annotations “aren’t always guaranteed to show, even if you meet the requirements above,” and that it “regularly validates the sale price on your website.”

Three operational consequences:

  • Tiny markdowns earn nothing on Google. A product reduced from $100 to $95 is exactly 5% off, which is not “greater than 5%.” The sale price is still used as the current price, but there is no annotation.
  • A was-price needs a past. Where a history requirement applies, the base price must have been the real price for the stated number of days. A compare-at value the product was never sold at has no history to show.
  • Your theme is part of the feed. If the compare-at price is hidden on the landing page — by a theme setting, a market setting, or a variant mismatch — the landing-page condition is not met, whatever the feed says.

To see which products currently qualify, Google’s instructions are to open Products, select All products, click the filter icon, choose Has sale badge, and select Yes. For Black Friday on 27 November 2026, the base prices you intend to strike through need to be live and stable now, not raised in mid-November. Our Shopify Black Friday strategy hub places this in the wider twelve-week plan.

Is your compare-at price legal? Reference-pricing rules in the US and EU

This section is not legal advice. We are app developers, not lawyers. What follows summarises primary sources, with links, so you know which documents to read and which questions to take to someone qualified. State and national rules also exist that we have not surveyed.

United States: the FTC Guides Against Deceptive Pricing

The Federal Trade Commission’s guides are published at 16 CFR Part 233. Section 233.1 deals with former price comparisons, which is what a compare-at price is when it shows your own earlier price. The central test: “If the former price is the actual, bona fide price at which the article was offered to the public on a regular basis for a reasonably substantial period of time, it provides a legitimate basis for the advertising of a price comparison” (16 CFR § 233.1, via Cornell Law School’s Legal Information Institute).

The guide’s own example of a violation will sound familiar. A retailer whose usual price is $7.50 raises it to $10 for a few days, then “cuts” it back and advertises “Were $10, Now Only $7.50!” The guide calls this “obviously a false claim.” It also lists other fictitious comparisons, including a price “that was not maintained for a reasonable length of time, but was immediately reduced.”

The guide also says a former price “is not necessarily fictitious merely because no sales at the advertised price were made,” provided it was “openly and actively offered for sale, for a reasonably substantial period of time.” And it addresses trivial reductions: an advertiser who claims an item has been “Reduced to $9.99” when the former price was $10 “is misleading the consumer.”

If your compare-at price is a manufacturer’s suggested retail price rather than your own former price, a different section applies. Section 233.3 says a list price comparison misleads when list prices “do not in fact correspond to prices at which a substantial number of sales of the article in question are made” (16 CFR § 233.3). MSRP is not automatically safe because the manufacturer printed it.

European Union: the 30-day prior price rule

Directive (EU) 2019/2161, often called the Omnibus Directive, inserted Article 6a into the Price Indication Directive. The European Commission states that the amendments “enter into application from 28 May 2022” (European Commission, Price Indication Directive). The two operative paragraphs are short:

  • “Any announcement of a price reduction shall indicate the prior price applied by the trader for a determined period of time prior to the application of the price reduction.”
  • “The prior price means the lowest price applied by the trader during a period of time not shorter than 30 days prior to the application of the price reduction.”

Both are quoted from the Commission’s guidance notice on Article 6a (Commission Notice 2021/C 526/02, EUR-Lex). The difference from the US approach is the word lowest. Under the FTC guide the question is whether the former price was genuine. Under Article 6a the reference price for an announced reduction is the lowest price you charged in at least the previous 30 days, including earlier promotional prices.

Shopify’s own page gives the example: a product normally sells for 150 EUR and was promoted at 100 EUR within the last 30 days. If you now announce a reduction, the prior price is 100 EUR, not 150 EUR. You either apply the new reduction to the 100 EUR price, or apply it to the regular price and clearly disclose the lower earlier price as well — which, with only two price fields in the admin, needs extra text on the product page.

Other points from the same sources that affect how you use the field:

  • Member States can vary the rule. Article 6a allows different rules for goods that deteriorate or expire rapidly, a shorter period for products on the market for less than 30 days, and, for progressive reductions, treating the price before the first reduction as the prior price. The Commission’s guidance says the progressive-reduction option is to be “interpreted narrowly” and applies only when the price is reduced “without interruptions and without increasing the indicated ‘prior’ price.” Shopify adds that national legislation may require a period longer than 30 days.
  • MSRP comparisons fall under a different law. Shopify’s page says comparisons to external prices are not subject to the Price Indication Directive but are subject to the Unfair Commercial Practices Directive, and that if you use the compare-at feature for an external price, “you should make that comparison clear to customers to avoid confusion.”
  • Shopify does not check this for you. The page describes no mechanism that validates your 30-day history. It states: “You’re responsible for reviewing this information and applying it to your business.”

A date worth writing down if you sell into the EEA: thirty days before Black Friday 2026 is 28 October. Any promotional price you run from that date onward is a candidate for the lowest prior price when you announce a Black Friday reduction, subject to the national rules where you sell.

On our own app: Auto Markdown applies progressive steps and keeps the original price in the compare-at field throughout. Whether that fits the progressive-reduction option depends on the law of the country you sell into. The app does not make that determination, and neither can we.

A working rule that satisfies both

Our judgment, not a legal standard: the compare-at field should only contain a price the product was openly sold at, for a sustained period, immediately before the current reduction — and if you ran a deeper promotion in the last 30 days and sell to the EEA, that lower price instead. A value that meets this test will also tend to satisfy Google’s base-price history requirement, because both ask the same question: was this number ever really the price?

Removing or reverting compare-at prices after a sale

Ending a compare-at sale is two edits per variant, and the order matters.

  1. Restore Price to the original value. During the sale, the compare-at field is where the original is stored. Copy it back into Price.
  2. Clear the compare-at field. Empty, not zero.
  3. Save, then check a collection page and a product page.

Each way of getting this wrong has a distinct signature. Clear the compare-at field without restoring Price, and the sale price becomes the permanent price while the record of the original disappears. Restore Price but leave the compare-at value in place, and nothing shows on the storefront because the two are equal — but the product still matches a “compare-at price is set” condition and sits in your Sale collection at full price.

Reverting at scale

For a catalog-sized sale, re-import the untouched pre-sale export with the overwrite option selected. Because a blank cell in an included column overwrites the stored value as blank, products that had no compare-at price before the sale return to having none. This only works if the export predates every sale edit; an import restores the file, not your intentions. If you changed a regular price mid-sale, correct that row before re-importing.

For a collection-sized sale, the bulk editor works: put each row’s Compare-at value back into Price, then clear the Compare-at cells. Do both before saving so there is no moment at which the storefront shows the wrong combination.

Reverting automatically

None of the native methods above reverts a compare-at price. A revert needs something that stored the original price when the sale began and acts on it later. Sale-scheduler apps do this on a date. Auto Markdown does it on an event: when a marked-down product sells, the original price is restored, the compare-at field is cleared, and the rule’s timer starts again. That suits slow-moving stock. It does not suit a weekend promotion with a fixed end time; use a scheduler for that.

Common mistakes

  1. Typing 0 to remove a compare-at price. Zero is a value. Shopify’s documentation says it is not the same as empty, and lists $0.00 among the conflicting values that stop a collection page showing a sale. Clear the field.
  2. Putting one variant on sale and ignoring the rest. The product page will look right and the collection card will not. Set or clear the field on every variant as a single decision.
  3. Overwriting Price before copying it. The admin has two price fields and no history. If the original is not in the compare-at field or an export, it is gone.
  4. Inflating the compare-at price to reach a rounder percentage. The FTC guide’s fountain-pen example describes exactly this, and Google’s base-price history requirement will often withhold the annotation anyway. Set depth by changing Price.
  5. Leaving compare-at prices in place after the sale. A strikethrough that never ends stops being a former price and becomes a claim you cannot support. It also keeps products in automated Sale collections indefinitely.
  6. Expecting an automatic discount to draw a strikethrough. Discounts apply in the cart and at checkout. Shopify’s FAQ says product-page strikethroughs for discounts need an app or custom work.
  7. Reading markdown cost from the Discounts column. It will show zero. Compare-at sales reduce gross sales instead, and only your own records show by how much.
  8. Testing only from your own country. Catalog adjustments, fixed prices, and the Hide compare-at setting are all per market. A sale that looks correct in Miami can be missing in Munich.

FAQ

What does compare at price mean on Shopify?

It is a reference price stored on each variant, intended to hold the product’s original price while the Price field holds the lower sale price. When it is higher than Price, themes display it struck through next to the sale price, usually with a sale badge. It is display data only: customers are charged the Price.

Why is my compare at price not showing on Shopify?

Check four things in order. The compare-at price must be higher than Price, not equal or lower. Every variant needs consistent values, because Shopify documents conflicting variant pricing as the reason a sale shows on product pages but not collection pages, and $0.00 does not count as empty. The theme section you are viewing must support sale pricing. And if only some countries are affected, check that market’s catalog pricing and its Hide compare-at setting.

How do I set a compare at price for all variants?

Select the products, click Bulk edit, add the Price and Compare-at price columns, and enter values for every variant row; dragging a cell’s fill handle copies a value down the column. For a large catalog, export a CSV, fill the two price columns with spreadsheet formulas, and import with the overwrite option. Either way, leave no variant with a different, empty, or zero value unless that is deliberate.

How do I calculate the compare at price percentage?

Subtract Price from the compare-at price, divide by the compare-at price, and multiply by 100. For a compare-at price of $80 and a Price of $60, that is 20 ÷ 80, or 25% off. Shopify does not store the percentage; themes that show one calculate it from the two fields, so rounding your sale price can change the number displayed.

Why is my Shopify sale badge not showing?

The badge is drawn by the theme using the same comparison as the strikethrough, so first confirm the compare-at price is higher than Price on every variant. If the strikethrough appears but the badge does not, the cause is in the theme: badges may be limited to certain templates, or the product may be sold out, in which case Dawn shows the sold-out badge instead. If the sale is an automatic discount, there is no badge because the product data records no sale.

How do I remove a compare at price in Shopify?

Open the product or variant, delete the contents of the Compare-at price field so it is empty, and save. Do not enter 0, because Shopify treats zero as a value rather than as empty. If the product was on sale, restore Price to the original amount first, otherwise the sale price becomes permanent. For many products, clear the column in the bulk editor or import a CSV with blank Compare-at price cells.

Do discount codes apply on top of a compare at price sale?

Yes, unless you prevent it. Discounts are calculated in the cart from the price being charged, which during a sale is the sale price. A 20% code on a product already marked down 30% results in a 44% total reduction. Shopify’s discounts FAQ does not describe a setting that excludes products with a compare-at price, so limit each discount to collections that do not contain sale items.


— Palm Beach Themes is a Miami-based Shopify app studio. We use the apps we sell, so every claim in this post comes from our own merchant testing.

If the compare-at prices you worry about are the ones on slow-selling stock — set late, deepened by hand, and forgotten afterwards — that is the specific job Auto Markdown does: it marks down by rule, writes the original price to the compare-at field, stops at your floor, and restores the price when the product sells. There is a free plan for 50 tracked products, so you can test it on one collection before trusting it with more.