An online shop needs structured data that fits each type of page: Product and Offer on product pages, ProductGroup for products with variants, BreadcrumbList for the breadcrumb trail and Organization, including your returns policy, on the home page or about page. That data has to match what a visitor sees. One correct source per page works better than three apps that each output their own version.
What does structured data do for an online shop?
Structured data is a fixed-format description of the information on a page, usually written as JSON-LD in the code. For a shop, it tells search engines which name, price, currency and stock status belong to a product. Google uses that data, among other things, to decide whether a page is eligible for product results that show price, availability or ratings. Eligibility is not a guarantee: Google’s general structured data guidelines treat correct markup as a requirement, not a promise.
womens waterproof rain jacket
- fashionshop-example.co.uk › women › jacketsWomen’s rain jacketsBrowse our collection of jackets for every season.
- rainwear-example.co.uk › rain-jackets › noorWomen’s rain jacket Noor, waterproof with hoodBreathable rain jacket in three colours. In stock, returns within the shop’s return window.
- cyclingblog-example.co.uk › adviceHow to choose a good rain jacketWhat to look for in waterproofing and ventilation.
If you want the basics first, read structured data explained. This article covers the choices that are specific to online shops.
Which types belong on which page?
Not every page gets every type. For each kind of page, pick the type that describes its content.
| Page | Type | What it describes | Watch out for |
|---|---|---|---|
| Product page without variants | Product with Offer | Name, image, price, currency, availability | Price in the markup equals the price shown |
| Product page with variants | ProductGroup with a Product per variant | The variants and how they differ | Each variant has its own URL that preselects it |
| Category page | BreadcrumbList | Where the page sits in your structure | At least two steps in the trail |
| Home page or about page | Organization (or OnlineStore) | Name, logo, contact details, identifiers | Once, on one page, not on every page |
| Returns page | MerchantReturnPolicy nested in Organization | Return window, country, conditions | Merchant Center settings take precedence |
| Blog post or buying guide | Article | Title, date, author | Only for editorial content |
What about FAQPage?
On 8 May 2026, Google announced in the Search Central changelog that the FAQ rich result has not appeared in Google since 7 May 2026. The related documentation was removed on 15 June 2026. FAQPage remains a valid type on schema.org. So do not add FAQPage expecting an expandable question block in Google. A good FAQ on a product or category page still helps visitors; see writing an FAQ that helps customers, Google and AI assistants.
Which fields does a product page need?
In its product documentation, Google separates two kinds of product results. Product snippets are for pages where you cannot buy the product directly, such as a review site. Merchant listings are for pages where the customer can buy it. An online shop belongs in the second group. According to the merchant listing documentation, the basics look like this:
Fields for a merchant listing
| Required | Recommended | |
|---|---|---|
| Product | name, image, offers (an Offer, not an AggregateOffer) | brand, gtin, sku, color, size, material, aggregateRating, review |
| Offer | price (above zero), priceCurrency | availability, itemCondition, shippingDetails, hasMerchantReturnPolicy |
A minimal block for a product without variants then looks like this. The shop, the product and the price are made up:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Women's rain jacket Noor, green, size M",
"image": "https://www.example.com/img/noor-green.jpg",
"brand": { "@type": "Brand", "name": "Downpour Rainwear" },
"sku": "NOOR-GREEN-M",
"offers": {
"@type": "Offer",
"price": "89.95",
"priceCurrency": "GBP",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
}A GTIN (the number behind the product barcode) and a brand name help a search engine match your product to the same product sold elsewhere. Shipping costs and return conditions are exactly what a customer looks for just before buying.
Ratings in your markup must also be visible on the page. Google’s review snippet guidelines require that the visitor can see the review and the average rating directly. What else belongs on a good product page, from copy to shipping information, is in the product page checklist.
How do you describe products with variants?
A jacket in four sizes and three colours is one product with twelve variants. Google has ProductGroup for this:
ProductGroupdescribes the parent product and gets aproductGroupID(the parent SKU) and aname.hasVariantholds the individual variants asProduct. A variant can also point back to the group withisVariantOf.variesBystates how the variants differ, such as colour or size.- Each variant gets its own ID (
skuorgtin) and a name that is more specific than the group name.
Google also asks for a separate URL per variant that preselects that variant, for example ?size=m&colour=green, with the right image, price and availability. If all variants live on one page, the group gets a single canonical URL without a variant selection.
What your platform does here by itself differs:
- Shopify has a Liquid filter called 0. According to its documentation, it outputs
Productfor a product without variants andProductGroupfor a product with variants. The filter only works for products and articles. - WooCommerce generates basic markup automatically. According to the WooCommerce documentation, the core outputs one combined product block for variable products, for performance reasons. If you want data per variant, you need an extension.
Where do the breadcrumb and returns policy belong?
The breadcrumb
The breadcrumb trail shows where a page sits in your shop: Home, Jackets, Rain jackets, Women’s rain jacket Noor. BreadcrumbList describes that trail as a list of ListItem entries, each with a position, name and item (the URL). The last entry may leave out the URL, in which case Google uses the URL of the page itself. The markup must match the breadcrumb the visitor sees.
Returns and shipping
Many shops repeat the returns policy in every product’s markup. Google recommends a different structure: put one general returns policy in Organization using hasMerchantReturnPolicy, on a page such as your returns page or about page. Use product-level markup only when a product has different terms.
Keep Google’s order of precedence in mind. According to the return policy documentation, settings in Merchant Center or Search Console override product-level markup, which in turn overrides markup in Organization. If Merchant Center lists different terms from your site, Merchant Center wins. Keep the two the same. Business details and Organization schema are covered further in consistent business information for search engines and AI.
How do you avoid duplicate or conflicting output?
Duplicate output happens easily in a shop that runs several apps or plugins. The theme outputs a product block, a review app adds a second one with the ratings, and an SEO app or plugin adds a third, sometimes with an old price from the cache. A search engine then sees three descriptions of the same product, possibly with different prices or stock levels. Here is how to find it:
Tracking down duplicate product blocks
- Pick a tricky pageOpen a product page that has variants and a discount. That combination shows the most errors.
- View the page sourceNot the inspector, which also shows output added by JavaScript. Search for application/ld+json.
- Count the blocksHow many blocks of type Product or ProductGroup are there?
- Compare with the screenPrice, currency and availability in each block should match what the visitor sees.
- Pick one sourceLet one theme or app output the product data and switch the others off, or let them only add fields.
Google recommends putting product markup in the initial HTML. According to the variant documentation, markup that only appears through JavaScript can lead to less frequent and less reliable processing.
How do you test structured data?
Use more than one check, because each tool looks at something different:
| Check | What it shows you |
|---|---|
| Rich Results Test | Which Google results the markup on a public page makes possible, plus errors and warnings |
| Schema Markup Validator | Whether the markup is valid according to schema.org, independent of Google |
| URL Inspection in Google Search Console | Whether Google found the structured data on the page |
| Per-feature reports in Search Console | Errors across your whole site after publication |
| Your own eyes | Whether price, stock and reviews in the markup match the page |
A passing test only proves that the syntax is correct. Whether the price in the markup is today’s price, you only see by comparing. Repeat the check after every change to your theme, apps or pricing rules.
Atlas, Outseen’s own research engine, reads the public HTML of fetched pages and the supported JSON-LD in it, such as product and breadcrumb. For every finding, Atlas records what it found, on which URL and when. Markup that only appears after JavaScript falls outside that research, and the report states that limit. A specialist checks whether the data matches the page, and after a change Atlas can check again.
Does structured data help with AI assistants?
In its guidance on AI features and your website, Google says AI Overviews and AI Mode need no special schema. Google does list as good practice that your structured data matches the visible text and that your Merchant Center data is up to date. Other AI assistants have their own methods, so do not count on an effect the provider does not describe itself. Product questions asked to AI are covered in GEO for online shops.
What does this mean for your online shop?
Do not start by adding more types. Start by asking how many product blocks your pages output now and whether they are correct. Take three product pages: one without variants, one with variants and one on sale. View the page source, count the blocks and compare price and stock with what the visitor sees. That is where you will find most errors.
If you run on Shopify or WooCommerce, first check what your theme or the core already outputs before you add an app. Put your returns policy in Organization once and keep it in line with Merchant Center. After every change to your theme, apps or pricing rules, repeat the same check.