Offer schema missing or incomplete
What Is This Issue
Product pages have a Product schema block but the nested Offer is absent or missing required fields, preventing Google from displaying price and availability in rich results.
Without Offer schema:
- Price and availability won’t show in search results
- Product rich results won’t display pricing information
- Users won’t see stock status (In Stock, Out of Stock)
- Google Shopping rich results won’t appear
- Price drop badges won’t display
- Product schema is incomplete for commercial visibility
A proper Offer schema should be nested inside Product schema and include: price, priceCurrency, availability, and optionally priceValidUntil, url, seller, itemCondition.
Why Is This Important
Offer schema is essential for e-commerce SEO:
- Product rich results: Enables price, availability, and review stars in search results
- Price drop badges: Google shows “Price drop” badges when
priceValidUntilis set - Availability signals: Helps users see if products are in stock before clicking
- Google Shopping: Required for Google Shopping rich results
- Conversion optimization: Users are more likely to click when they see current pricing
- AI search readiness: AI engines use Offer data to answer pricing queries accurately
Resolving this issue improves your e-commerce SEO health score by ensuring product pricing information is properly structured for search engines and AI systems.
How XeoPix Detects This
XeoPix follows these logical steps to detect missing or incomplete Offer schema:
-
Find Product schema: The crawler identifies pages with
Productschema blocks -
Check for
offersproperty: The crawler examines whether the Product schema has anoffersproperty -
Validate Offer structure: If
offersis present, the crawler checks for:@typeset toOfferorAggregateOfferpriceproperty (required)priceCurrencyproperty (required)availabilityproperty (required)
-
Check for completeness: The crawler also verifies:
priceValidUntilfor sale prices (recommended)urlproperty pointing to the product pagesellerproperty (recommended)
-
Trigger conditions: The issue is flagged when:
- Product schema exists but
offersproperty is missing - Offer exists but
priceis missing - Offer exists but
priceCurrencyis missing - Offer exists but
availabilityis missing
- Product schema exists but
How To Fix
-
Locate Product schema: Find pages with
Productschema (check your product detail pages) -
Add or complete the
offersproperty in your Product schema:For single price:
{ "@context": "https://schema.org", "@type": "Product", "name": "Product Name", "description": "Product description", "offers": { "@type": "Offer", "price": "29.99", "priceCurrency": "USD", "availability": "https://schema.org/InStock", "priceValidUntil": "2024-12-31", "url": "https://example.com/product-page", "seller": { "@type": "Organization", "name": "Store Name" } } }For multiple offers/variants, use
AggregateOffer:"offers": { "@type": "AggregateOffer", "lowPrice": "29.99", "highPrice": "49.99", "priceCurrency": "USD", "offerCount": "5" } -
Use correct values for key properties:
price: Numeric value as string (e.g., “29.99”)priceCurrency: ISO 4217 currency code (e.g., “USD”, “EUR”, “GBP”)availability: Use Schema.org URLs:https://schema.org/InStock,https://schema.org/OutOfStock,https://schema.org/PreOrder, etc.priceValidUntil: ISO 8601 date format (e.g., “2024-12-31”)
-
Keep price in sync with page - mismatches cause Google penalties
-
Validate with Google’s Rich Results Test
What We Store
Storage Level
Page Level — This issue is evaluated for each individual URL that contains structured data.
Database Table / Prisma Model
PageStructuredData
Stored Fields
| Field | Type | Description |
|---|---|---|
| schemaType | SchemaType | The type of schema (e.g., Organization, Person) |
| schemaFormat | SchemaFormat | The format of the schema (JSON-LD, Microdata, RDFa) |
| schemaIdentifier | String? | Unique identifier for the schema |
| rawJson | Json? | The raw JSON-LD or structured data content |
| schemaErrors | Json? | Array of validation errors found in the schema |
| isValidSchema | Boolean? | Whether the schema is valid according to validation |
| missingFields | Json? | Array of required fields that are missing |
Detection Dependencies
- The following data sources are required to evaluate this issue:
- HTML Document — The crawler parses the HTML to find structured data (JSON-LD, Microdata, RDFa)
- Structured Data Validation — The extracted schema is validated against Schema.org definitions
- Schema Parser — JSON-LD scripts, Microdata attributes, and RDFa markup are parsed
Examples
Example 1: Missing Offer Schema in Product
Problematic state (Product without Offer):
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation"
}Missing offers property
Corrected state:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation",
"offers": {
"@type": "Offer",
"price": "199.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"priceValidUntil": "2024-12-31",
"url": "https://example.com/headphones"
}
}Example 2: AggregateOffer for Multiple Offers
Corrected state (multiple sellers):
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Running Shoes",
"offers": {
"@type": "AggregateOffer",
"lowPrice": "89.99",
"highPrice": "129.99",
"priceCurrency": "USD",
"offerCount": "5",
"availability": "https://schema.org/InStock"
}
}Example 3: Incomplete Offer Schema
Problematic state (missing required properties):
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Smartphone",
"offers": {
"@type": "Offer",
"price": "599.99"
}
}Missing priceCurrency and availability
Corrected state:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Smartphone",
"offers": {
"@type": "Offer",
"price": "599.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}Unit Test
Test File
xeopix-crawling-v2/__tests__/seo-audit-checks/structuredDataRichResults/issue-232-offer-schema-missing.test.js
Purpose
Validates that the crawler correctly detects when a Product schema is missing the offers property or when the nested Offer is missing required fields.
Tested Function
runStructuredDataRichResults()
Issue Information
- Issue Number: 232
- Issue Code:
offer_schema_missing - Toggle Group:
structuredDataRichResults
Test Scenarios
Positive Test Cases
- Product with valid Offer: Product schema has a complete
offersproperty withpriceandpriceCurrency— no issue reported. - Multiple offers: Product schema has an array of offers, all with
priceandpriceCurrency— no issue reported.
Negative Test Cases
- Product missing offers property: Product schema exists but lacks the
offersproperty — issue is reported with message containing “Product schema is missing the “offers” property” andschemaTypeset toProduct. - Nested Offer missing price: Product has
offersbut the nested Offer is missingprice— issue is reported withvalidationErrorscontainingprice missing. - Nested Offer missing priceCurrency: Product has
offersbut the nested Offer is missingpriceCurrency— issue is reported withvalidationErrorscontainingpriceCurrency missing.
Boundary Cases
None.
Edge Cases
- Empty HTML:
<html></html>— no issue reported, no crash. - Malformed JSON-LD: Invalid JSON-LD content — no crash.
Expected Outcome
Pass
Issue should not be reported when a Product schema has a valid offers property with complete Offer data (including price and priceCurrency).
Fail
Issue should be reported when a Product schema is missing the offers property, or when the nested Offer is missing price or priceCurrency. The details.schemaType is Product and validationErrors contains the specific missing fields.
Validation
- Correct issue detection when Product schema lacks offers
- Correct issue detection when nested Offer is incomplete
- No issue detection when Product has valid or multiple offers
- Validation errors specify which fields are missing
- Graceful handling of empty HTML and malformed JSON-LD
Related Production Files
xeopix-crawling-v2/toggleGroups/structuredDataRichResults.jsxeopix-crawling-v2/issueCodes.jsxeopix-crawling-v2/utils/context.jsxeopix-crawling-v2/utils/issues.jsxeopix-crawling-v2/utils/schema.js
Coverage Summary
- Covers Product schema with valid Offer
- Covers Product schema with multiple offers
- Covers detection of missing offers property
- Covers detection of missing price in nested Offer
- Covers detection of missing priceCurrency in nested Offer
- Covers empty HTML resilience
- Covers malformed JSON-LD resilience
References
- Schema.org — Offer — Schema.org
- Schema.org — AggregateOffer — Schema.org
- Google — Product Offer Properties — Google Search Central