Product & Review Schema for Shopify and WordPress — Step-by-Step Implementation
Introduction: The Power of Rich Snippets
When you search for a product on Google, you don’t just see a title and a link. You often see results that include yellow stars, price ranges, availability status, and even shipping information directly in the search snippet. These are called Rich Snippets, and they are powered by a specific layer of technical SEO known as Schema.org markup (or Structured Data).
For e-commerce stores, rich snippets are a game-changer. They don’t just make your listing stand out visually; they provide critical decision-making data to potential buyers before they even click. This transparency significantly increases your Click-Through Rate (CTR) and can even improve your rankings by signaling to Google that your page is a highly relevant “Product” entity.
In this guide, we’ll dive deep into the implementation of Product and Review schema for the two most popular platforms: Shopify and WordPress.
Why Structured Data Matters: JSON-LD vs. The Rest
As we’ve discussed in our Shopify SEO: How to Rank Your Store guide, the modern web is built on “Entities.” Structured data gives search engines a clear, machine-readable vocabulary to understand these entities.
There are three main formats for structured data:
- Microdata: Nested directly within HTML tags using
itempropattributes. Difficult to maintain and prone to breaking during design changes. - RDFa: An extension to HTML5 similar to Microdata.
- JSON-LD (The Winner): A standalone block of JavaScript that lives in the
<head>or at the bottom of the<body>. Google explicitly recommends JSON-LD because it is decoupled from the visual HTML, making it easier to read, debug, and automate.
By implementing JSON-LD schema, you are effectively telling Google: “This isn’t just a collection of images and text; it is a Product with a specific Price, a verified set of Reviews, and a clear In-Stock status.”
The Anatomy of High-Impact Product Schema
To get the most out of your rich snippets, you must include as many “recommended” properties as possible. Google’s requirements are strict: if you miss a “required” property, the rich snippet won’t show. If you miss a “recommended” property, you’ll see a warning in Search Console, but the snippet might still appear.
Core Properties to Target:
- SKU / GTIN: Critical for matching your product against Google’s global product catalog.
- Brand: Helps establish the authority of the listing.
- Offer: This nested object contains the
price,priceCurrency, andavailability. - AggregateRating: This is what generates the yellow stars. It requires a
ratingValue(e.g., 4.5) and areviewCount(e.g., 120). - Review: Individual review snippets. Google loves to see at least one or two detailed reviews nested within the product schema.
Shopify Implementation: Advanced Liquid Scripting
Shopify themes often come with basic schema, but they frequently fail on variable products (products with different sizes/prices) or miss critical Review data from third-party apps.
The “Multi-Offer” Liquid Template
Add this to your snippets/product-schema.liquid. This version handles multiple variants and ensures Google sees the correct price range.
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "Product",
"name": {{ product.title | json }},
"url": "{{ shop.url }}{{ product.url }}",
{% if product.featured_image %}
"image": [
"https:{{ product.featured_image | img_url: '1024x1024' }}"
],
{% endif %}
"description": {{ product.description | strip_html | json }},
"sku": "{{ product.selected_or_first_available_variant.sku }}",
"brand": {
"@type": "Brand",
"name": {{ product.vendor | json }}
},
"offers": [
{% for variant in product.variants %}
{
"@type": "Offer",
"url": "{{ shop.url }}{{ variant.url }}",
"priceCurrency": "{{ shop.currency }}",
"price": "{{ variant.price | divided_by: 100.00 }}",
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/{% if variant.available %}InStock{% else %}OutOfStock{% endif %}"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
],
{% comment %}
Integrating with Review Apps (e.g., Judge.me or Shopify Reviews)
Check your app's documentation for the correct metafield names.
{% endcomment %}
{% if product.metafields.reviews.rating_count %}
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "{{ product.metafields.reviews.rating_value }}",
"reviewCount": "{{ product.metafields.reviews.rating_count }}"
}
{% endif %}
}
</script>
WordPress Implementation: Customizing WooCommerce Schema
WooCommerce has built-in schema, but it’s notorious for generating “Warnings” in Google Search Console due to missing fields like brand or description. You can use a hook to “filter” and clean up the schema before it’s outputted.
The Advanced WordPress Filter
Add this to your theme’s functions.php. It allows you to inject custom data like “Brand” which isn’t a native WooCommerce field.
add_filter( 'woocommerce_structured_data_product', 'custom_update_woocommerce_product_schema', 10, 2 );
function custom_update_woocommerce_product_schema( $markup, $product ) {
// Ensure the Brand is set (custom logic)
$markup['brand'] = [
'@type' => 'Brand',
'name' => 'Your Brand Name'
];
// Add GTIN if you work with a custom field
$gtin = get_post_meta( $product->get_id(), '_custom_gtin', true );
if ( $gtin ) {
$markup['gtin13'] = $gtin;
}
// Ensure description isn't empty
if ( empty( $markup['description'] ) ) {
$markup['description'] = wp_strip_all_tags( $product->get_short_description() );
}
return $markup;
}
Validation: The Search Console Lifecycle
Implementing the code is only 50% of the battle. The other 50% is validation and monitoring.
- Real-Time Testing: Use the Google Rich Results Test. Paste your product URL or the raw JSON-LD code. It will highlight errors (missing required fields) and warnings (missing recommended fields).
- Search Console Monitoring: Once live, wait 3-5 days. Check the Merchant Listings and Product Snippets reports in the “Enhancements” section of GSC. This is the only way to see if Google is actually accepting your markup across your entire catalog.
For a broader view of site health, see our Technical SEO Audit Basics.
Common Pitfalls and Policy Issues
- Price Mismatches: If your schema says $49 but the user sees $59 on the page (due to sales or currency conversion), Google will flag it as a policy violation and may disable your rich snippets entirely.
- “Out of Stock” Logic: Ensure your availability schema updates in real-time. Showing “In Stock” in search for an “Out of Stock” product leads to a terrible user experience and high bounce rates.
- The “No Reviews” Gap: If you have zero reviews, do not include an empty
aggregateRatingblock. It’s better to omit it entirely than to serve empty data.
Conclusion
Structured data is the bridge between your content and Google’s understanding of the commercial web. By implementing a robust Product and Review schema in JSON-LD, you ensure that your Shopify or WordPress store isn’t just “another page,” but a verified, authoritative shopping destination. Start with the basics, solve the Search Console warnings one by one, and watch your click-through rates skyrocket.