Schema markup for ecommerce is JSON-LD code that tells Google exactly what each page sells: the product, its price, availability, reviews, variants, and your store's return and shipping policies. For a store, the core set is Product with Offer on product pages, ProductGroup for variants, BreadcrumbList on product and collection pages, and Organization (as OnlineStore) with a return policy on the home page. It won't lift your rankings by itself, but it makes your listings eligible for merchant listings, product snippets and review stars, which change how you look in search.
This guide is for e-commerce and Shopify teams who want to implement schema correctly, not just install an app and hope. You'll get the exact types to use on each page template, copy-ready JSON-LD that follows Google's current documentation, a step-by-step Shopify rollout, and a table of the errors that quietly cost stores their rich results. For the broader picture of what schema is, start with our schema markup guide.
What schema markup does for an ecommerce store
Search engines can read your product page without help, but they have to infer what the numbers on it mean. Structured data removes the guesswork. Google describes it as "a standardized format for providing information about a page and classifying the page content," and recommends JSON-LD "if your site's setup allows it." For a store, that means you can state plainly that 18.00 is a price in US dollars, that the item is in stock, and that 212 reviews average 4.7 stars.
Correct markup does three jobs for a store:
- Rich result eligibility. Product markup is the gateway to merchant listing experiences (price, availability, shipping and returns shown in results and on Google surfaces) and to product snippets with review stars.
- Consistent product data. Google says "providing both structured data on web pages and a Merchant Center feed maximizes your eligibility to experiences," and some experiences combine data from both. Markup that matches your feed reduces mismatches.
- A clear brand entity. Organization markup tells Google your store's name, logo, social profiles and policies in one place.
Most of the web still skips the product layer. In the HTTP Archive's 2024 Web Almanac, Product JSON-LD appeared on just 0.77% of pages, far behind generic types such as WebSite and Organization. Every store sells products, so that gap is an opportunity for anyone who gets the details right.
View the data
| Value | |
|---|---|
| WebSite | 12.7% |
| Organization | 7.2% |
| BreadcrumbList | 5.7% |
| WebPage | 1.5% |
| Product | 0.8% |
Source: HTTP Archive, Web Almanac 2024, Structured Data chapter
One expectation to set early: schema is not a ranking factor. Google's John Mueller put it bluntly in April 2025: "Structured data won't make your site rank better." Its value is in how your result looks and what Google can show, which we cover in depth in schema markup vs standard SEO.
The schema types every store needs
Google's search gallery lists 25 structured data features as of October 2026. A store needs only a handful of them. Map each type to the page template that should carry it, so your theme outputs it once, everywhere it belongs.
| Schema type | Page template | What it can earn in Google | Must include |
|---|---|---|---|
| Product + Offer | Product pages | Merchant listings and product snippets | name, image, offers with price and priceCurrency |
| ProductGroup | Product pages with variants | Variant-aware merchant listings | name, plus productGroupID, variesBy, hasVariant |
| AggregateRating / Review | Nested inside Product | Review stars on product results | ratingValue and ratingCount or reviewCount |
| BreadcrumbList | Product and collection pages | Breadcrumb trail in results (desktop) | itemListElement with at least two ListItem entries |
| Organization (OnlineStore) | Home page or about page | Brand details, return and shipping policies | No required properties; add name, url, logo and policies |
| Article | Blog posts | Better article titles, images and dates | No required properties; add headline, image, datePublished |
Collection pages are the most common place stores over-mark. Google says "Product rich results only support pages that focus on a single product (or multiple variants of the same product)." Listing twenty products as Product objects on a collection page won't earn rich results. Give collection pages BreadcrumbList, solid copy and clean internal links instead.
Product and Offer markup for merchant listings
Google splits product results into two experiences. Merchant listings are "for pages where customers can purchase products from you," and product snippets are "for product pages where people can't directly purchase the product," such as review sites. A store's product pages are merchant listing pages, so build to those requirements.
Source: Google Search Central, Merchant listing structured data, 2026
The required set is short: a Product needs name, image and offers, and the Offer needs price and priceCurrency. The recommended set is where stores win or lose eligibility for richer displays. On the Product, Google recommends properties including aggregateRating, brand.name, description, a GTIN, mpn, sku, color, size and material. On the Offer, it recommends availability, itemCondition, url, priceValidUntil, shippingDetails and hasMerchantReturnPolicy.
Here is a complete, valid example for a simple product with no variants:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Merino Crew Sock",
"image": [
"https://example.com/images/merino-crew-sock-1x1.jpg",
"https://example.com/images/merino-crew-sock-4x3.jpg"
],
"description": "Midweight merino wool crew sock with a cushioned sole.",
"sku": "MCS-001",
"gtin14": "00012345678905",
"brand": {
"@type": "Brand",
"name": "Example Socks"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.7,
"reviewCount": 212
},
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sock",
"price": "18.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
}
</script>
Rules that keep merchant listings eligible
- Match the page exactly. Google's policies say structured data "must be a true representation of the page content," and it "may attempt to verify merchant listing product data before showing the information in search results." A sale price in the markup that the page doesn't show is a mismatch.
- Use full schema.org URLs for enumerations, such as
https://schema.org/InStock, rather than plain text. - Ship it in the initial HTML. Google recommends "putting Product structured data in the initial HTML for best results." Markup injected late by JavaScript is a common cause of missing or stale prices.
- Add identifiers you actually have. A real GTIN, MPN or SKU helps Google match your product to the same item elsewhere. Never invent one to fill the field.
For a Shopify-specific walkthrough of this template, see our product schema guide for Shopify.
We'll benchmark your store against your top three competitors on Google and AI answers, flag the product pages ready to move and prioritize the fixes, with the revenue math.
Product variants with ProductGroup
If one product page sells several sizes or colors, mark it up as a ProductGroup with each variant as a nested Product. Google's variant documentation lists only name as required on the group, and recommends productGroupID (the parent SKU), variesBy and hasVariant. The allowed variesBy values are color, size, suggestedAge, suggestedGender, material and pattern, each written as a full schema.org URL.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"name": "Merino Crew Sock",
"productGroupID": "MCS",
"brand": {
"@type": "Brand",
"name": "Example Socks"
},
"variesBy": [
"https://schema.org/size",
"https://schema.org/color"
],
"hasVariant": [
{
"@type": "Product",
"sku": "MCS-M-GRY",
"name": "Merino Crew Sock, Medium, Gray",
"size": "M",
"color": "Gray",
"image": "https://example.com/images/mcs-gray.jpg",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sock?variant=101",
"price": "18.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
},
{
"@type": "Product",
"sku": "MCS-L-NVY",
"name": "Merino Crew Sock, Large, Navy",
"size": "L",
"color": "Navy",
"image": "https://example.com/images/mcs-navy.jpg",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sock?variant=102",
"price": "18.00",
"priceCurrency": "USD",
"availability": "https://schema.org/OutOfStock"
}
}
]
}
</script>
Each variant carries its own Offer, so each can have its own price, URL and stock status. Give each variant a URL that preselects it (on Shopify, the ?variant= parameter does this) so the price Google reads matches what the shopper lands on. Shopify's structured_data Liquid filter follows the same model: per Shopify's docs, it outputs a product with no variants as Product and a product with variants as ProductGroup.
Reviews and ratings that stay eligible
Star ratings are the most visible schema win for a store, and the easiest to break. Nest aggregateRating or individual review objects inside the Product, so the item being reviewed is clear. Google's review snippet rules require ratingValue and at least one of ratingCount or reviewCount, and ratings default to a five-point scale unless you set bestRating and worstRating.
Three rules matter most for stores:
- Only mark up reviews shoppers can see on the page. If your review app loads reviews in a widget, make sure the count and average in the markup match what renders.
- Don't add stars to your Organization. Google says that if "the entity that's being reviewed controls the reviews about itself," its LocalBusiness and Organization pages lose eligibility for star review features. Store-wide ratings belong on product pages, not your brand markup.
- Use one source of truth. In November 2025 Google clarified that site owners "should avoid using multiple ways of indicating what's being reviewed." Many stores end up with the theme and a review app both outputting ratings. Keep one.
Organization, return and shipping policies
Return and shipping policies used to be repeated inside every Offer. Google now recommends you "provide a global return policy for your business under Organization markup instead," and it added merchant-level shipping policy support in November 2025. Put Organization markup on your home page or a single about page; it doesn't need to appear on every page. For ecommerce sites, Google recommends the OnlineStore subtype.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "OnlineStore",
"name": "Example Socks",
"url": "https://example.com",
"logo": "https://example.com/images/logo.png",
"sameAs": [
"https://www.instagram.com/examplesocks"
],
"hasMerchantReturnPolicy": {
"@type": "MerchantReturnPolicy",
"applicableCountry": "US",
"returnPolicyCountry": "US",
"returnPolicyCategory": "https://schema.org/MerchantReturnFiniteReturnWindow",
"merchantReturnDays": 30,
"returnMethod": "https://schema.org/ReturnByMail",
"returnFees": "https://schema.org/FreeReturn"
}
}
</script>
For an Organization-level return policy, Google requires either applicableCountry plus returnPolicyCategory (and merchantReturnDays for a finite window), or a merchantReturnLink to your policy page. Add returnFees, returnMethod and refundType where they apply. Shipping policy goes under hasShippingService, and loyalty programs under hasMemberProgram; see our Organization schema guide for the full brand setup.
Which return policy source wins
If your policy is defined in more than one place, Google uses this order, strongest first:
| Priority | Where the policy is set | When to use it |
|---|---|---|
| 1 | Content API for Shopping return settings | Large catalogs managed by API |
| 2 | Merchant Center or Search Console settings | Most stores with a Merchant Center account |
| 3 | Product-level merchant listing markup | Products with a different policy, such as final sale items |
| 4 | Organization-level markup | Your default policy for the whole store |
The practical takeaway: if Merchant Center already holds your return settings, those win, so keep your markup consistent with them rather than contradicting them.
Breadcrumbs and collection pages
BreadcrumbList shows Google where a page sits in your store. Google requires an itemListElement with at least two ListItem entries, each with a name and an item URL, and position 1 marks the start of the trail. You can leave the URL off the last item, in which case Google uses the URL of the page itself.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Socks",
"item": "https://example.com/collections/socks"
},
{
"@type": "ListItem",
"position": 2,
"name": "Merino Socks",
"item": "https://example.com/collections/merino-socks"
},
{
"@type": "ListItem",
"position": 3,
"name": "Merino Crew Sock"
}
]
}
</script>
Two details trip stores up. First, since January 2025 Google shows breadcrumbs "only" on desktop results, not mobile, so don't judge the markup by your phone. Second, Shopify product URLs can be reached through several collection paths. Pick one canonical trail per product, usually its primary collection, so the markup is stable and matches your visible breadcrumb.
On collection pages, BreadcrumbList is usually the only schema you need. Spend the remaining effort on what does move collection rankings: unique intro copy, internal links and a clean canonical setup.
Our free $100M AI Visibility Roadmap, built from 7,960 live pages and 197 A/B tests, shows how stores get cited by ChatGPT, Google AI Overviews and Perplexity.
How to add schema on Shopify, step by step
Most Shopify themes already output some markup, so the job is usually auditing and completing it, not starting from zero. Work in a duplicate theme, then publish.
- Audit what you have. Run a product URL, a collection URL and your home page through our schema validator. Note every JSON-LD block, its type and which properties are missing.
- Find who outputs each block. In the theme code editor, search for
ld+jsonandstructured_data. Then check your apps: review, SEO and bundle apps often inject their own Product or rating markup. - Remove duplicates. Keep one Product block per product page. If the theme's block is incomplete, either extend it or replace it, but don't run two side by side.
- Complete the Product template. Use the
{{ product | structured_data }}filter or a custom Liquid snippet that outputsProductGroupfor variant products, with brand, GTIN or SKU, availability and ratings from your one review source. - Add Organization with your return policy to the home page template, using
OnlineStore. Our schema markup generator builds a starting block you can edit. - Add BreadcrumbList to product and collection templates, matching the breadcrumb shoppers see.
- Test before you publish. Preview the duplicate theme and run Google's Rich Results Test on one product of each kind: simple, variant, out of stock and on sale.
- Publish and monitor. Watch the Merchant listings, Product snippets and Breadcrumbs reports in Search Console for new errors over the following weeks.
If you prefer to understand the format before editing Liquid, our JSON-LD guide explains the syntax and how to nest types.
Common ecommerce schema errors and fixes
Search Console groups problems into errors (the item is ineligible) and warnings (a recommended property is missing). Fix errors first, then the warnings that unlock features you want, such as shipping and returns.
| Symptom | Likely cause | Fix |
|---|---|---|
| "Missing field price" or "offers" | Variant with no price, or markup rendered by JavaScript after load | Output Offer price server-side in Liquid for every variant |
| Two Product items on one page | Theme and an app both output Product markup | Disable one source; keep a single complete block |
| Price in results doesn't match the page | Sale price, currency or market not reflected in markup | Generate price from the same variable the page displays |
| Review stars missing | Rating not nested in Product, zero reviews, or ratings on Organization | Nest aggregateRating in Product; omit it when there are no reviews |
| Return policy warnings on every product | No Organization-level or Merchant Center return policy | Add MerchantReturnPolicy to OnlineStore markup on the home page |
| Breadcrumbs not visible on phone | Expected: Google shows breadcrumbs on desktop only | No fix needed; verify on desktop or in the Rich Results Test |
Watch for manual actions too. Google's policies warn that a structured data issue "can result in a manual action," which removes rich result eligibility. Marking up hidden reviews, fake prices or content that isn't on the page is the fastest way to get one.
Your schema rollout plan
Prioritize by revenue. Fix Product and Offer on your top-selling product templates first, because that's where merchant listings and stars show up. Add ProductGroup for variant products next, then Organization with your return policy, then breadcrumbs. Validate every change, monitor Search Console, and re-test whenever you change themes or install an app that touches product pages.
Schema works best on a store that already ranks, because rich results only appear on pages Google chooses to show. If you want a second set of eyes on both, our technical SEO team can review your templates, or you can talk to us about where your store stands against its competitors.
Book a free 30-minute call. We'll show you where you stand against your top competitors and the fixes worth making first.