Product Schema Markup: How to Get Star Ratings and Prices in Google

·6 min read

If you sell anything on your site and your search results don't show a price, star rating, or "In stock" label underneath, you're leaving clicks on the table. The listings that do show those things have one thing in common: valid Product schema markup.

Product schema is the JSON-LD blob that tells Google "this page is a thing for sale, here's the price, here's what people rated it." Get it right and Google may upgrade your listing to a rich result. Get it wrong — or use the wrong review structure — and Google's manual actions team will revoke your rich snippet eligibility, sometimes for the entire domain.

What Product Schema Unlocks

A plain blue-link result gets maybe 20-30% of the search clicks for a non-branded query. A result with a star rating, price, and stock status pulls something closer to 35-50% in the same position. Google calls these "merchant listing experiences" in their docs, and they include:

  • Product snippets — star rating, review count, price, stock status under your title
  • Merchant listing visual experience — bigger product card with image, often in the Popular Products carousel
  • Google Shopping eligibility — free organic shopping listings (you don't need ads to qualify)

The catch: every one of these requires valid Product structured data with specific fields populated correctly. Missing a single required field can knock you out of eligibility entirely.

The Minimum Viable Product Schema

This is the smallest blob that qualifies a page for product rich results. Drop it in the <head> or anywhere in <body>:

<script type="application/ld+json">
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Vintage Leather Messenger Bag",
  "image": [
    "https://example.com/photos/bag-1x1.jpg",
    "https://example.com/photos/bag-4x3.jpg",
    "https://example.com/photos/bag-16x9.jpg"
  ],
  "description": "Full-grain leather messenger bag with brass hardware and a 15-inch laptop sleeve.",
  "sku": "BAG-VLM-001",
  "brand": {
    "@type": "Brand",
    "name": "Hayes Leather Co"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/vintage-leather-messenger-bag",
    "priceCurrency": "USD",
    "price": "189.00",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition"
  }
}
</script>

The required fields for product rich results in 2026 are: name, image, and either offers, review, or aggregateRating. Google strongly recommends description, sku, and brand on top of that. Without offers, you can't get a price snippet — and prices are usually the highest-CTR enhancement.

Adding Reviews and Ratings

Star ratings come from aggregateRating and review. They're separate fields that do different jobs.

aggregateRating is the summary — "4.5 stars from 87 reviews." That's what shows up in the search snippet:

"aggregateRating": {
  "@type": "AggregateRating",
  "ratingValue": "4.5",
  "reviewCount": "87",
  "bestRating": "5",
  "worstRating": "1"
}

review is an array of individual review objects. You don't need to ship every review you have — five to ten recent ones is plenty. Each one needs an author, a rating, and a body:

"review": [
  {
    "@type": "Review",
    "author": {"@type": "Person", "name": "Marisa T."},
    "datePublished": "2026-03-14",
    "reviewBody": "Bought this for my wife and the leather is exactly as described. Good weight, no plastic feel.",
    "reviewRating": {
      "@type": "Rating",
      "ratingValue": "5",
      "bestRating": "5"
    }
  }
]

Two rules that get sites banned from rich results:

  1. Reviews must come from real customers. Google's spam team actively hunts down sites that ship aggregateRating without any actual review system on the page. If a human auditor visits your URL and can't find the reviews the schema claims exist, you lose rich result eligibility on the whole domain.
  2. Self-serving reviews don't count. A business reviewing its own products, or a parent company reviewing a subsidiary's products, gets filtered. The reviewer needs to be a customer or independent third party.

Stock Status and Pricing

availability accepts a small set of Schema.org URLs. Use the right one — Google reads them literally:

  • https://schema.org/InStock
  • https://schema.org/OutOfStock
  • https://schema.org/PreOrder
  • https://schema.org/BackOrder
  • https://schema.org/Discontinued
  • https://schema.org/LimitedAvailability

If the schema says InStock and the user lands on a sold-out product page, Google logs it. Repeated mismatches between the schema and the live page state are a manual-action trigger. Render this from your inventory data, not a hardcoded value.

For sales, use priceValidUntil and the lowPrice/highPrice pattern with AggregateOffer:

"offers": {
  "@type": "AggregateOffer",
  "priceCurrency": "USD",
  "lowPrice": "149.00",
  "highPrice": "189.00",
  "offerCount": "12",
  "availability": "https://schema.org/InStock"
}

Use AggregateOffer when one product page covers multiple variants (sizes, colors) at different price points. Use a single Offer when there's one SKU with one price.

Common Mistakes That Kill Rich Results

These are the failure modes I see most often when sites have valid-looking schema but no rich snippets in the wild:

Schema on category pages instead of product pages. Product rich results require the schema to be on a single-product detail page. A category or collection page with multiple Product blobs doesn't qualify — use ItemList with linked products instead.

Image array missing or wrong aspect ratios. Google wants 1:1, 4:3, and 16:9 versions of the product image. A single image works but limits which carousels you're eligible for. The images need to be publicly crawlable — no robots.txt blocks, no auth walls.

Price as a number instead of a string. Schema.org's price field expects a string, not a number. "price": "189.00" is right. "price": 189.00 will validate but sometimes fails to populate the snippet because of locale formatting issues.

Review schema without a visible review section. If your review array references reviews that aren't actually rendered on the page, Google's algorithm and manual auditors will flag it. The schema must reflect what users see.

Conflicting data between schema and visible page. Schema says $189, page says $169. Schema says InStock, page shows "Sold Out." Google trusts the visible page over the schema and may suppress rich results entirely.

Validate Before You Ship

Two checks every product page deserves before it goes live:

  1. Run the markup through our Structured Data Validator — catches missing required fields, malformed JSON, and unsupported types in seconds.
  2. Run the live URL through Google's Rich Results Test — confirms eligibility and shows which rich result types qualify.

If you're starting from scratch, the Schema Markup Generator builds a Product blob with the right structure (offers, brand, aggregateRating) and handles the URL formatting Schema.org expects.

What's Changed in 2026

Two updates worth knowing about:

  • Merchant returns and shipping. Google now uses MerchantReturnPolicy and OfferShippingDetails as soft ranking signals for shopping queries. Adding them won't trigger a new visual feature, but missing them means you're competing against listings that have more structured info than you.
  • hasMerchantReturnPolicy and shippingDetails are nested inside the Offer object, not at the top level. The current Google docs at developers.google.com/search/docs/appearance/structured-data/product show the full schema.

The pattern hasn't changed: complete schema, accurate to the visible page, validated before deploy. If those three are in place, Google's structured data quality algorithm tends to take care of the rest.

Ready to try it?

Create JSON-LD structured data for your website. Support for Article, LocalBusiness, Product, FAQ, and more schema types.

📋 Schema Markup Generator — Free Online Tool

Get notified about new SEO tools

More free tools coming soon — keyword research, sitemap generator, and more.