UXFixUXFix
Language
Audit my store free
Audit findings

Product Page Stock Availability UX: How We Score Rule PDP-006

Abdulhameid Grandoka·4 September 2026
Product Page Stock Availability UX: How We Score Rule PDP-006

Product page stock availability UX comes down to one rule: every product page must state, in plain text next to the price and the Add to Cart button, whether the selected variant is in stock, low in stock or out of stock. UXFix audits this as rule PDP-006, severity high. A shopper, or an AI shopping agent acting for one, should never have to click Add to Cart to find out the answer.

What rule PDP-006 checks, and how we score it

PDP-006 reads: the product page states the stock or availability state explicitly, as text, for the variant currently selected, before the shopper acts. We rate it high severity because it sits on the decision path. A shopper who cannot tell whether the thing is available cannot decide to buy it, and neither can a shopping agent working on their behalf.

The category is decision and the check method is dom. Decision means the rule governs whether the shopper commits, not how pleasant the page feels. Dom means our crawler reads the rendered document for a text node that names the state, rather than inferring it from a button colour, a swatch style or an image.

We look for three things in order. Is there a state at all? Is it within the same viewport as the price and the Add to Cart button? And does it change when the shopper changes size, colour or pack quantity? The verdict comes out as one of three results.

  • Pass: a plain-text state (in stock, low stock with a number, out of stock, or a dated backorder) sits next to the price and button, and it updates per variant.
  • Partial: a state exists but it is only implied (a greyed button, a colour dot), or it appears only after a variant is picked, or it sits below the fold, or it does not distinguish low stock from in stock.
  • Fail: no state anywhere on the page before Add to Cart, so the shopper learns the truth in the cart, at checkout, or in a post-order email.

In practice the crawler loads the page with no variant chosen, records what it can read, then selects each option in turn and reads again. A page can pass for the default variant and fail for the third size, and the lowest result is the one that counts. That is deliberate. Your shopper does not buy the default. They buy their size.

PDP-006 is one of the 115 checks in our rule book, and it correlates closely with the out of stock handling rules further down the funnel. The full list is in All 115 Ecommerce Checkout UX Rules We Audit Against. This article is about this one rule, because it is the one stores most often assume they pass and do not.

The three states, and the copy that passes

There are three states a shopper cares about, plus one that behaves like a fourth. Each needs different words, and each has a common way of going wrong.

State Copy that passes Copy that fails or only partially passes Position
In stock 'In stock' or 'In stock, ships today' Nothing. Silence is not a state. Under the price, above Add to Cart
Low stock 'Only 3 left' 'Selling fast', 'Almost gone', a red dot Same place and type size as in stock
Out of stock 'Out of stock. Back 14 March' or 'Notify me' A disabled grey button, a hidden variant, a 404 In place of Add to Cart
Backorder or preorder 'Preorder, ships 2 May' Ship date shown only in the cart Same as in stock

In stock is the state everyone skips. The argument goes that the button is enabled, so obviously the item is available. That argument fails the moment a shopper has been burned on another store, and most have. The word costs you nothing and it removes a question from the shopper's head before they reach for the button.

The strongest form of the in stock line adds a dispatch promise: 'In stock, order by 3pm for dispatch today'. It answers the second question, when will I get it, in the same glance. It is also the line we most often see on stores that pass the rest of the product page rules as well, which is not a coincidence. A store that has wired its inventory into the page tends to have wired its carrier cut-offs in too.

Low stock is the state that does the most work for conversion and the one most often abused. A number is the honest form. 'Only 3 left' tells the shopper something true and specific. 'Selling fast' tells them nothing they can check, and it reads as pressure. If your inventory system cannot give a reliable per-variant count, show 'Low stock' without a number rather than a number you cannot stand behind.

Out of stock has to answer the follow-up question: what now? A bare 'Out of stock' passes PDP-006 because the state is explicit, but it leaves the rest of the page doing nothing. The out of stock section below covers what the rest of the page should do.

Backorder and preorder items are technically available, but the shopper's decision depends on the date, so the date belongs in the availability line. 'Ships in 3 to 5 weeks' revealed in the cart is too late, and it converts a decision the shopper thought they had made into one they now have to make again.

If you ship from more than one location, or a partner fulfils some SKUs, the state still has to resolve to one honest line per variant. 'In stock at our partner, ships in 5 to 7 days' is fine. Showing 'In stock' because one warehouse somewhere has a unit, then quoting a three week lead time in the cart, fails the rule in spirit and usually in the data as well.

Variants are where most stores lose points. A product with six sizes may be in stock for four, low for one and out for one. The state that passes is the state of the size the shopper has selected, updated the instant they select it. Three rules for variant products:

  • Show a page-level state before any variant is picked, even if it is 'Available in 4 of 6 sizes'.
  • Mark unavailable options on the selector itself, with a strikethrough or a 'Sold out' tag on the swatch, and keep them selectable so the shopper can register for a restock alert.
  • When a variant is selected, replace the page-level line with that variant's exact state.

The words should match what your fulfilment can honour. If 'In stock' on the page can become 'on backorder' in the confirmation email, you have a data problem that copy cannot fix, and it will surface as a refund and a one-star review.

What failing, partially affected and passing product pages look like

The patterns below come from stores we have audited, with identifying details removed. Each one is labelled with the verdict our crawler gave it and the specific pattern that earned that verdict.

Failing: no availability state anywhere before Add to Cart

The page shows the price, a size selector with a size chosen, and an enabled Add to Cart button, with no text anywhere that says whether the selected size is in stock. This is the most common fail we record, and it looks fine at first glance. Every element is where it should be. The problem is what is not there.

The shopper picks a size, clicks the button, and gets an inline error in the cart drawer saying the item is unavailable in that size. From the shopper's side, the store lied by omission. From the crawler's side, there is no text node to read, so the state is unknown and the rule fails.

Stores in this condition usually have the data. The inventory count is sitting in the product JSON the page loads. It is just never rendered into anything a human or an agent can see until it is used to block the add.

Partially affected: state implied by colour or button only

One size swatch is greyed out and the Add to Cart button is disabled, but no text names the state. This store knows the state and is trying to communicate it. The trouble is that it communicates it only through styling.

A grey swatch means nothing on its own; on plenty of sites grey means 'not selected'. A colour-blind shopper cannot tell which sizes are available, and neither can a crawler. WCAG success criterion 1.4.1, Use of Color, exists for exactly this pattern, because colour cannot be the only way information is conveyed. The full wording is in the WCAG 2.1 specification.

Our crawler marks this partial rather than fail because the DOM does carry a signal: a disabled attribute on the button and a class on the swatch. But an attribute is not a state a shopper can read, and an agent parsing the page for availability text finds none. The fix is one line of visible text: 'Size M: sold out. Notify me when it is back.'

Partially affected: low stock indicator hidden below the fold

The price and Add to Cart sit above the fold with no state. The 'Only 2 left' message appears inside a delivery information panel two screens down. The store has the right message and even the right honesty. It has put it where a shopper deciding at the button will never see it.

In a mobile session the shopper reaches Add to Cart within the first screen; the low stock line is in the delivery accordion several hundred pixels further down. It also fails to update when the variant changes, because that block is rendered once at page load.

This pattern deserves a mention because the people who built it did the hard part, the inventory integration, and lost the value on placement. Move the line next to the price, bind it to the variant selector, and it becomes a pass.

Passing: explicit, per-variant, next to the button

The selected size shows 'In stock, order by 3pm for dispatch today' directly under the price, and an unavailable size on the selector is struck through and labelled Sold out. Everything the shopper needs is inside one glance. The state is text, it is specific to the selected variant, it sits between the price and the button, and unavailable options are labelled on the selector rather than hidden.

A shopper who switches to the struck-through size sees the line change to 'Sold out. Expected back 14 March. Notify me.' and the button changes to a notify action.

For the crawler, there is a text node containing the word stock adjacent to the price element, it changes on variant selection, and the schema.org Offer markup for that variant carries availability InStock. That is a clean pass.

Passing: out of stock, handled as a page rather than a dead end

Out of stock can pass, and pass well. A page in this condition states the fact in the first line under the price, gives a restock date, offers the notify action where the button would have been, and uses the remaining space to show in stock alternatives from the same category.

Nothing here is unusual or expensive. It is the decision to treat the out of stock page as a page.

AI Shoppers
AI shopping agents already visit your store. Can they buy?
Scored against agent-commerce specs · 0–100
Test agent readiness →

Why does a missing stock state cost you the sale?

The cost is easy to underestimate because it rarely shows up as a bounce on the product page. The shopper does not leave when they cannot see the state. They add the item, hit the wall in the cart or at checkout, and leave there. In your analytics it looks like cart abandonment, and cart abandonment already has plenty of causes to hide behind.

70%
average cart abandonment rate across 49 published studies · Baymard
31%
of product pages we audit show no availability text before Add to Cart · UXFix, n=200
24%
of product pages we audit show a state only after a variant is selected · UXFix, n=200

Baymard's aggregate of cart abandonment studies puts the average just over 70%. Not all of that is fixable UX, but the portion caused by discovering something late in the flow is, and availability is one of the things shoppers discover late most often. It sits alongside shipping cost and delivery date in the category of information the store had and chose not to show.

There are three distinct ways a missing or implied state costs you.

The first is the false add. The shopper commits to a size, adds it, and is told no. Some of them pick another size. Most have already decided this store is unreliable, and go and buy the same thing somewhere that told them the truth up front. You paid to acquire that session and handed it to a competitor.

The second is the missing nudge. A true low stock number is one of the few pieces of information that makes a shopper decide faster without any manipulation. If you have three left of a popular size and say nothing, you have left the timing of that decision to the shopper's calendar rather than your inventory.

The third is the review. A shopper who buys an item the page called available, then receives a backorder email, does not blame the warehouse. They write a review about the store. Every subsequent shopper reads it above the fold, which is more prominent than the availability line would ever have been.

We wrote about the downstream version of this problem in Why Out-of-Stock Pages Quietly Kill Your Conversion Rate. The short version is that a store which is honest about availability on the product page loses the sale of that one item and keeps the shopper. A store that hides it loses both. Availability also appears among the reasons shoppers leave in Why Shoppers Leave Your Product Page Without Buying: 12 Fixes, and of the twelve it is the cheapest to fix, because the data already exists in your platform.

Out of stock product page best practices

An out of stock page is still a product page, and the shopper who landed on it still wanted the thing. Your job is to keep them, either for the restock or for something else you sell. The pattern that passes PDP-006 and does that job has five parts.

Before

The page shows the price, a size selector with size M silently missing, and an Add to Cart button that does nothing when clicked. There is no text about stock anywhere. The shopper assumes the site is broken and leaves.

After

The first line under the price reads Size M: out of stock. Back in stock 14 March. The Add to Cart button is replaced with Notify me when it is back and an email field. Below the description, four in stock alternatives from the same range appear with their own In stock labels.

State it first. The out of stock line goes where the in stock line would have been: under the price, above the button. Not in a banner at the top of the page, which reads as a site-wide notice, and not in a tooltip that only appears on hover.

Give a date or say you do not have one. 'Back in stock 14 March' is best. 'Expected back in 2 to 3 weeks' is fine. 'Restock date to be confirmed' is honest and still better than silence. What fails the shopper is a bare 'Out of stock' with nothing after it, because they cannot tell if that means tomorrow or forever.

Replace the button, do not just disable it. A disabled Add to Cart button reads as broken. A 'Notify me when back in stock' button in the same position reads as a store that is on top of its inventory. It also captures an email address you can act on the day the delivery arrives.

Show alternatives with their own state. If you recommend three similar products, each card needs its own In stock label. Sending a shopper from one out of stock page to another is worse than showing nothing.

Keep the URL alive. Deleting or redirecting an out of stock product page throws away its search ranking and any links pointing to it. If the product is permanently discontinued, say so on the page and point to the replacement, and keep the page for as long as it earns visits.

Temporarily out and permanently discontinued are different states and need different words. 'Discontinued. Replaced by the 2024 model' with a link keeps the shopper moving. Calling a discontinued item 'out of stock' invites notify me sign-ups you can never honour, and every one of those is a future email you will not want to send.

Do
  • Put the out of stock line in the exact position the in stock line normally occupies.
  • Keep out of stock variants visible on the selector, marked Sold out, and selectable for a restock alert.
  • Give a restock date, a range, or an explicit to be confirmed.
Don’t
  • Remove the variant from the selector so the shopper wonders whether the size exists at all.
  • Leave an Add to Cart button enabled when the add will fail in the cart.
  • Show a low stock number your inventory system cannot verify per variant.

A note on the low stock indicator, since it is where the honesty question bites hardest. Countdown-style urgency, an 'Only 2 left' that resets on every visit, is the fastest way to teach your shoppers to disbelieve every message on the page, including the true ones. It is also the fastest way to teach an AI agent the same lesson, and agents remember. Show the count your system reports, cap it at a sensible threshold (many stores show a number only at five or fewer), and never show a number for a made-to-order or drop-shipped item.

Why AI shopping agents need explicit stock state in the DOM

Human shoppers infer. They see a grey swatch, a disabled button and a red dot, and they work out what it means, mostly correctly. AI shopping agents do not infer well from styling, and many of them do not render the page at all.

An agent fetching your product page to answer 'is this in stock in a medium?' is looking for text or structured data that says so. If the state lives only in a CSS class or a hover tooltip, the agent's answer is either 'unknown' or a guess, and a guess in your favour is not what you want when it leads to a failed order and a shopper who blames you.

This is why PDP-006 is scored with the dom method. We are checking what is in the document, not what a person would perceive from the pixels. Three things make a product page legible to an agent on this rule.

First, the state is a text node, not an attribute or an image. 'Out of stock' as visible text in the DOM passes. A disabled attribute on a button does not, because it does not tell the agent why the button is disabled. An availability badge rendered as an image with no alt text is the same problem in a different costume.

Second, the state is present on initial render for a default variant, not only after JavaScript runs in response to a click. Many agents fetch the HTML and run limited or no script. If your page is blank on availability until the shopper picks a size, the agent sees blank. Render a default state server-side and let the client update it as the selection changes.

Third, the state is mirrored in structured data. Schema.org's Offer type has an availability property with a fixed set of values, and it is the single most reliable signal an agent can read. The full list is on schema.org/ItemAvailability.

json
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Merino crew neck",
  "offers": [
    {
      "@type": "Offer",
      "sku": "MCN-NAVY-M",
      "price": "89.00",
      "priceCurrency": "GBP",
      "availability": "https://schema.org/InStock",
      "inventoryLevel": { "@type": "QuantitativeValue", "value": 3 }
    },
    {
      "@type": "Offer",
      "sku": "MCN-NAVY-L",
      "price": "89.00",
      "priceCurrency": "GBP",
      "availability": "https://schema.org/OutOfStock"
    }
  ]
}

Two details in that example matter. The offers are per variant, each with a SKU, so the agent can answer a size-specific question. And the availability value is a URL from the fixed vocabulary, not free text. An agent can match InStock, LimitedAvailability, OutOfStock, PreOrder and BackOrder without interpretation. 'Selling fast' in a free-text field is as useless to an agent as it is to a shopper. The inventoryLevel property is optional, and you should include it only when the number is real.

The structured data and the visible text must agree. We regularly find pages where the markup says InStock for every variant because it was generated once from a template, while the visible page says sold out. An agent that trusts the markup recommends a product the shopper cannot buy. The next time that agent is asked about your store, it has a reason to prefer a competitor. We cover how agents build that picture of a store in Why ChatGPT and Gemini Don't Recommend Your Store.

There is a practical test you can run today without any tooling. Open a product page, view the raw page source rather than the inspector, and search for the word stock. If it appears only inside a script block, or not at all, agents cannot see your availability state and you are relying on them to guess. Then pick a size that you know is sold out and check that the visible line, the button label and the markup all change together. If any one of the three disagrees with the others, that is the bug to fix first.

Frequently asked questions

What should an out of stock product page show?

An out of stock product page should state 'Out of stock' in plain text directly under the price for the selected variant, give a restock date or an explicit 'to be confirmed', replace the Add to Cart button with a notify me action that captures an email, and show in stock alternatives from the same category with their own availability labels. The URL should stay live so its search ranking and inbound links are preserved, and the schema.org Offer markup should carry availability OutOfStock so shopping agents do not recommend a product nobody can buy.

How do you indicate low stock on a product page?

Show the true count as text next to the price, in the same position and type size as the in stock message: 'Only 3 left' or 'Low stock: 3 remaining'. Show a number only when your inventory system can verify it per variant, cap the display at a threshold such as five or fewer so the message stays meaningful, and never show a count for made-to-order or drop-shipped items. Avoid vague urgency phrases like 'selling fast' and any counter that resets between visits, because both teach shoppers and AI agents to disbelieve the rest of your page.

Should out of stock variants be hidden or shown greyed out?

Show them, label them, and keep them selectable. Hiding a sold out size makes shoppers wonder whether the product comes in that size at all, and it removes the chance to capture a restock alert. A greyed swatch alone is only a partial pass on PDP-006, because colour is not a state a shopper or an agent can read and it fails WCAG 1.4.1. The pattern that passes is a strikethrough or a 'Sold out' tag on the swatch, and when the shopper selects it, an availability line that says 'Sold out' with a date and a notify action in place of Add to Cart.

Does a disabled Add to Cart button count as an explicit stock state?

No. A disabled button tells the shopper that something is preventing the purchase but not what, and it reads as a bug as often as it reads as sold out. It gives an AI agent even less, because a disabled attribute carries no reason. We score a disabled button with no accompanying text as partial at best. Add one line of visible text above or in place of the button, such as 'Size L: out of stock. Notify me', and the same page becomes a pass.

Keep reading

Audit findingsPDP-001: Price Visible Above the Fold on Desktop and Mobile, Without Scrolling or TappingRule PDP-001 fails more mobile product pages than any other pricing rule we audit, and the fix is usually a layout change you can ship this week.Audit findingsShipping Cost on the Product Page: How PDP-004 Is ScoredPDP-004 is one of the most-failed critical rules in our audits: here is exactly what a passing product page shows, where it shows it, and how to make the data readable by AI shopping agents.Audit findingsOut-of-Stock Product Page Best Practices: Rule PDP-007 ScoredA sold-out page that only greys out the button loses the shopper and the return visit. Here is exactly what rule PDP-007 checks, with fail, partial and pass examples.

See what UXFix finds on your own store

115 rules, your product page, cart and checkout, a screenshot of every issue. About four minutes.

Audit my store free