Skip to content
Browse all guides

Issue #155 · important

Issue 155

What is this issue?

Product schema is present on a product page, but the nested Offer schema is missing or incomplete. The Offer schema provides critical pricing and availability information that enables rich results showing price, availability status, and price validity.

Without a properly structured Offer:

  • Google cannot display price and availability in product rich results
  • Price drop badges won't appear in search results
  • Availability status (In Stock, Out of Stock, Preorder) won't be shown
  • Users may click through to products with outdated pricing information

A complete Offer schema should be nested inside Product schema and include: price, priceCurrency, availability, priceValidUntil, url, and optionally priceSpecification, hasMerchantReturnPolicy, shippingDetails, etc.

Why does it matter?

Offer schema is essential for e-commerce SEO and user experience:

  • 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
  • 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:

    {
      "@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"
        }
      }
    }
    
  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. For multiple offers, use AggregateOffer:

    "offers": {
      "@type": "AggregateOffer",
      "lowPrice": "29.99",
      "highPrice": "49.99",
      "priceCurrency": "USD",
      "offerCount": "5"
    }
    
  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: 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"
  }
}

Example 3: 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"
  }
}

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 exists, the crawler checks:

    • Is it an object or array?
    • Does it have @type set to Offer or AggregateOffer?
  4. Check required properties: The crawler verifies the Offer has:

    • price (or lowPrice/highPrice for AggregateOffer)
    • priceCurrency
    • availability
  5. Check recommended properties: The crawler also looks for:

    • priceValidUntil
    • url
    • seller
  6. Trigger conditions: The issue is flagged when:

    • Product schema exists BUT offers property is missing
    • offers exists but price is missing
    • offers exists but priceCurrency is missing
    • offers exists but availability is missing or uses invalid values

References