offers
offers · Required by Google
Appears in
What is it?
An offer to provide a product, including its price, currency, availability, and condition. The offers property nests an Offer object (or AggregateOffer for price ranges) inside a Product, connecting the product to its commercial terms. This is the field that turns a product description into a purchasable listing in Google Search, Shopping, and AI-powered product comparisons.
Without offers, a Product entity is just a catalog entry. With it, search engines know the product can be bought, for how much, and whether it is in stock.
Why this matters for AEO
When a shopper asks an AI assistant "How much does the Nike Air Max 90 cost?", the engine pulls price and priceCurrency from the offers object. When someone asks "Is the Patagonia Nano Puff in stock?", the engine reads availability. When a user asks "Where can I buy a wool coat under $50?", the engine compares offers data across multiple Product entities to build a filtered answer.
Structured offer data is the foundation of AI-powered shopping. Without it, AI engines cannot compare prices, check stock, or recommend purchase options for your products.
What the specs say
Schema.org: Demand, Offer. An offer to provide this item. Use businessFunction to indicate the kind of transaction offered, i.e. sell, lease, etc. View on schema.org
Google: Required. "A nested Offer to sell the product." View Google docs
How to find your value
- price — Product page price, ecommerce platform pricing field
- priceCurrency — Your store's currency (USD, EUR, GBP, etc.)
- availability — Inventory system, stock status field
- itemCondition — Product listing (New, Refurbished, Used)
- url — The canonical URL of the product page
- priceValidUntil — Sale end date, promotion calendar
- seller — Your business name or Organization entity
Format and code
Expected type: Offer or AggregateOffer
Single offer (most common)
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Men's Leather Oxford Shoes",
"offers": {
"@type": "Offer",
"url": "https://example.com/oxford-shoes",
"priceCurrency": "USD",
"price": "119.99",
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/InStock"
}
}
Key Offer properties
price— Number or TextpriceCurrency— Textavailability— URLitemCondition— URLurl— URLpriceValidUntil— Dateseller— Organization
Availability values
- In stock —
https://schema.org/InStock - Out of stock —
https://schema.org/OutOfStock - Pre-order —
https://schema.org/PreOrder - Back order —
https://schema.org/BackOrder - Discontinued —
https://schema.org/Discontinued
Item condition values
- New —
https://schema.org/NewCondition - Refurbished —
https://schema.org/RefurbishedCondition - Used —
https://schema.org/UsedCondition - Damaged —
https://schema.org/DamagedCondition
AggregateOffer (price ranges)
Use AggregateOffer when a product has multiple offers at different prices (e.g., from multiple sellers or for different variants):
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Wool Winter Coat",
"offers": {
"@type": "AggregateOffer",
"lowPrice": "39.99",
"highPrice": "129.99",
"priceCurrency": "USD",
"offerCount": "4",
"availability": "https://schema.org/InStock"
}
}
Offers on product variants
Each variant gets its own Offer:
{
"@context": "https://schema.org/",
"@type": "ProductGroup",
"name": "Wool Winter Coat",
"brand": {
"@type": "Brand",
"name": "Good brand"
},
"hasVariant": [
{
"@type": "Product",
"name": "Small Green Coat",
"sku": "44E01-M11000",
"color": "Green",
"size": "small",
"offers": {
"@type": "Offer",
"url": "https://www.example.com/coat?size=small&color=green",
"priceCurrency": "USD",
"price": 39.99,
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/InStock"
}
}
]
}
Source: Google Product Variants documentation
Common invalid patterns:
- Missing
priceCurrency:"price": "119.99"without a currency code - Price with currency symbol:
"price": "$119.99"(use numeric value only) - Free-text availability:
"availability": "In Stock"(use the full schema.org URL) - Nested offers without
@type: omitting"@type": "Offer"inside the object
Webflow implementation
Static pages
Add the full offers object in Page Settings > Custom Code (Head):
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Handmade Ceramic Mug",
"offers": {
"@type": "Offer",
"url": "https://yoursite.com/ceramic-mug",
"priceCurrency": "USD",
"price": "28.00",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
}
</script>
CMS template pages
Map Webflow CMS price and availability fields to the Offer properties:
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "{{wf {"path":"name","type":"PlainText"} }}",
"offers": {
"@type": "Offer",
"url": "{{wf {"path":"slug","type":"PlainText"} }}",
"priceCurrency": "USD",
"price": "{{wf {"path":"price","type":"PlainText"} }}",
"availability": "https://schema.org/InStock"
}
}
</script>
Webflow Commerce products have built-in price fields. For standard CMS collections, use a plain text or number field for price.
Note: Dynamic availability (InStock vs. OutOfStock) requires conditional logic. Webflow's native CMS does not support conditional JSON-LD output. Schema HQ or custom code is needed for dynamic availability.
In Schema HQ
The value is read from Webflow CMS price field, detects the currency from your site settings, and builds the complete Offer object. It handles AggregateOffer for multi-variant products and can map a CMS availability field to the correct schema.org URL values.
Real examples
From an ecommerce schema guide:
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Men's Leather Oxford Shoes",
"image": [
"https://example.com/photos/1x1/photo.jpg",
"https://example.com/photos/4x3/photo.jpg"
],
"description": "Premium full-grain leather oxford shoes for formal occasions.",
"sku": "0446310786",
"mpn": "925872",
"brand": {
"@type": "Brand",
"name": "Acme Shoes"
},
"offers": {
"@type": "Offer",
"url": "https://example.com/oxford-shoes",
"priceCurrency": "USD",
"price": "119.99",
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/InStock"
}
}
Source: VJ SEO Marketing Ecommerce Schema Guide
Related fields
- name · the product title
- brand · who makes or sells the product
- sku · merchant-specific product identifier
- gtin · global trade item number
- image · product photos
FAQ
What is the difference between Offer and AggregateOffer?
Use Offer for a single price point from one seller. Use AggregateOffer when you want to show a price range across multiple offers or variants. AggregateOffer uses lowPrice, highPrice, and offerCount instead of a single price.
How do I handle sale prices?
Include the current (sale) price in the price field and add priceValidUntil with the sale end date. Google displays the listed price in rich results. There is no separate "original price" property in schema.org for showing a strikethrough price.
Is availability required by Google?
Availability is Recommended, not Required. But without it, Google cannot show stock status in rich results, and your products may rank lower in Shopping results compared to listings that do include availability. Use the full schema.org URL (e.g., https://schema.org/InStock), not plain text.