Skip to content
Browse all guides

Issue #232 · important

Issue 232

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 does it matter?

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 priceValidUntil is 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 to fix it

  1. Locate Product schema: Find pages with Product schema (check your product detail pages)

  2. Add or complete the offers property 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"
    }
    
  3. 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")
  4. Keep price in sync with page - mismatches cause Google penalties

  5. Validate with Google's Rich Results Test

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"
  }
}

How PixyScan detects this

PixyScan follows these logical steps to detect missing or incomplete Offer schema:

  1. Find Product schema: The crawler identifies pages with Product schema blocks

  2. Check for offers property: The crawler examines whether the Product schema has an offers property

  3. Validate Offer structure: If offers is present, the crawler checks for:

    • @type set to Offer or AggregateOffer
    • price property (required)
    • priceCurrency property (required)
    • availability property (required)
  4. Check for completeness: The crawler also verifies:

    • priceValidUntil for sale prices (recommended)
    • url property pointing to the product page
    • seller property (recommended)
  5. Trigger conditions: The issue is flagged when:

    • Product schema exists but offers property is missing
    • Offer exists but price is missing
    • Offer exists but priceCurrency is missing
    • Offer exists but availability is missing

References