Availability is a current offer fact, not a permanent product attribute. It must reflect the selected variant, market, and transaction state visible to the shopper.
Core schema.org values
| Value | Use when | Do not use when |
|---|---|---|
InStock |
selected offer can currently be purchased | inventory tracking is merely disabled without confirming purchase state |
OutOfStock |
selected offer cannot currently be purchased due to stock state | item is a preorder or backorder with a valid purchase action |
PreOrder |
purchase is accepted before release under stated terms | launch is historical and item is now sold out |
BackOrder |
purchase is accepted for later fulfilment | buy button is disabled |
Discontinued |
product is no longer offered and state is explicit | temporarily sold out |
OnlineOnly |
offer availability is specifically online-only | as a substitute for current stock |
LimitedAvailability |
limited state is real and supported | to create urgency without evidence |
Use complete https://schema.org/... URLs in structured data unless the framework deliberately handles vocabulary expansion.
Real conflict: The Woobles
Observed July 27, 2026:
Visible buy state: Sold out
Structured Product offer 1: InStock
Structured Product offer 2: InStock
This is a high-impact conflict because a retrieval system may repeat the structured value. The repair is to connect the offer to the same selected-variant state used by the buy button.
Real historical state: Mattel Creations
The collector-doll page exposed a current out-of-stock offer alongside historical launch and preorder information. Historical preorder terms must not cause the current offer to remain PreOrder indefinitely.
Store timeline fields separately:
launch_date: historical date
preorder_window: historical interval
current_availability: OutOfStock
market: CA
currency: CAD
Variant and market scope
A product can be:
- in stock in one size and sold out in another
- available in the US and unavailable in Canada
- available for one-time purchase but not subscription
- purchasable on backorder with a future fulfilment message
Therefore every finding should retain variant ID, URL, market, currency, and timestamp.
Shopify Liquid mapping
For a straightforward selected variant:
{% assign current_variant = product.selected_or_first_available_variant %}
{% if current_variant.available %}
https://schema.org/InStock
{% else %}
https://schema.org/OutOfStock
{% endif %}
This simple mapping is not enough for preorder or backorder programs. Those require explicit business state and visible customer terms.
Do not infer from inventory quantity alone
Shopify inventory policy can allow purchase after quantity reaches zero. A zero quantity may therefore be purchasable. Conversely, positive inventory does not guarantee a market can purchase the variant.
The public purchase action is the operational source to reconcile with inventory and structured data.
Field-level record
{
"canonical_url": "https://example.com/products/item",
"variant_id": "123",
"market": "CA",
"visible_state": "Sold out",
"structured_state": "https://schema.org/InStock",
"purchase_action_enabled": false,
"verified_at": "2026-07-27",
"result": "conflict"
}
Acceptance criteria
- selected variant buy state and Offer availability agree
- market and currency context are retained
- preorder/backorder has visible terms
- historical launch state is not treated as current
- sold-out and in-stock fixtures are both tested
- review apps and SEO apps do not emit stale duplicate offers
- cache invalidation is considered after inventory changes
Related guide: Fix duplicate Product JSON-LD.