Rich Snippets is the content missing from a regular search engine results page such as review count, star rating, price and availability.

*Updated 2020 - including Magento 2 Websites.

Please note that Magento 1.x sites are no longer supported by Adobe. Running a Magento 1.x webstore beyond June 2020 poses serious security risks. Read more here.

Including schema markup in your product listings can give a customer a more detailed snapshot of your what you are offering; showing images and other attributes in Google search results. This can increase click through rates by 20-30%.

Sadly, Magento does not provide Rich Snippets “out of the box” but fear not! Williams Commerce have put together this helpful guide of how to Add Rich Snippets to Magento products using Schema.org Tags.

What are schema.org tags?

Schema.org tags enable us to describe our page content through structured microdata. Giving search engine spiders as much information about our page enables site indexing to be more accurate and produce better search results. The best thing about adding microdata to your Magento product pages is that they enable rich snippets on search engine results pages.

Adding Schema.Org Microdata To Simple Products

In order for any of this to work you will need to firstly set up Schema.org tags on a simple product page. The information required as a minimum is name, price, and availability and it is also key to include review information to show the star rating. We will be using the  ProductOffer, and Aggregate Rating schemas for this task.

Warning: Never edit the core files- ensure to copy these phtml files into the correct directory in your package/theme 

The files we will be editing:

  • app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml
  • app/design/frontend/[package]/[theme]/template/catalog/product/view/media.phtml
  • app/design/frontend/[package]/[theme]/template/catalog/product/view/type/default.phtml
  • app/design/frontend/[package]/[theme]/template/catalog/product/price.phtml
  • app/design/frontend/[package]/[theme]/template/review/helper/summary.phtml

* NOTE: When adding data remember to use Meta tags for information that is different (IE: currency) and for all enumerated information use the link tag.

Setting Up A Product Item Scope

app/design/frontend/[package]/[theme]/template/catalog/product/view.phtml

Begin by declaring an itemscope of product on line 41.

<div class=”product-view” itemscope itemtype=”http://schema.org/Product” itemid=”#product_base”>

If you are only configuring simple product you can ignore the itemid as this sets up a link between parent product schema and the children product offers. This id can be whatever you want it to be as this static information is for references and not being indexed itself.

Tag the product name on Line 50

h1 itemprop=”name”><?php echo $_helper->productAttribute($_product,$_product->getName(), ‘name’) ?></h1>

Product Short description on Line 81

<div class=”std” itemprop=”description”><?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), ‘short_description’) ?></div>

We can also use Meta tags to include any other information we want about the base product inside of the product scope. These are just two examples.

<meta itemprop=”url” content=”<?php echo $_product->getUrlModel()->getUrl($_product, array(‘_ignore_category’=>true)); ?>” />

<meta itemprop=”sku” content=”<?php echo $_product->getSku() ?>” />

Adding The Product Image Property

app/design/frontend/[package]/[theme]/template/catalog/product/view/media.phtml

You will need to make the change in order to declare the product image in two places, Line 40 and Line 62.

$_img = ‘<img itemprop=”image” id=”image” src=”‘.$this->helper(‘catalog/image’)->init($_product, ‘image’).'” alt=”‘.$this->escapeHtml($this->getImageLabel()).'” title=”‘.$this->escapeHtml($this->getImageLabel()).'” />’;

$_img = ‘<img itemprop=”image” src=”‘.$this->helper(‘catalog/image’)->init($_product, ‘image’).'” alt=”‘.$this->escapeHtml($this->getImageLabel()).'” title=”‘.$this->escapeHtml($this->getImageLabel()).'” />’;

Setting Up Default Product Offers Scope

app/design/frontend/[package/[theme]/template/catalog/product/view/type/default.phtml

Having set up a a basic product scope, lets now set up a simple offer which includes price and availability. We do this to keep the offer scope separate depending on different product types.

Open up default.phtml and wrap everything in an Offer Itemscope starting on Line 28.

<div itemprop=”offers” itemscope itemtype=”http://schema.org/Offer”>…</div>

Then we can add a Meta tag for the product currency on Line 30…

<meta itemprop=”priceCurrency” content=”<?php echo Mage::app()->getStore()->getCurrentCurrencyCode();?>” />

and links for the Item Availablity on Lines 34 and 36.

<?php if ($_product->isAvailable()): ?>

<p class=”availability in-stock”><link itemprop=”availability” href=”http://schema.org/InStock”><?php echo $this->__(‘Availability:’) ?> <span><?php echo $this->__(‘In stock’) ?></span></p>

<?php else: ?>

<p class=”availability out-of-stock”><link itemprop=”availability” href=”http://schema.org/OutOfStock”><?php echo $this->__(‘Availability:’) ?> <span><?php echo $this->__(‘Out of stock’) ?></span></p>

<?php endif; ?>

Adding Product Price

app/design/frontend/[package]/[theme]/template/catalog/product/price.phtml

Price, however, is a bit trickier; you will have to dive into the complex price template file, which while powerful can appear overwhelming. Since we only want to show the basic non-sale price right now there are two cases to look for:

span itemprop=”price” class=”price” id=”price-excluding-tax-<?php echo $_id ?><?php echo $this->getIdSuffix() ?>”>…</span>

<span class=”regular-price” id=”product-price-<?php echo $_id ?><?php echo $this->getIdSuffix() ?>”>

<?php echo str_replace(‘class=”price”‘, ‘class=”price” itemprop=”price”‘, $_coreHelper->currency($_price + $_weeeTaxAmount, true, true)); ?>

The second piece of code allows us to target the price inside the $_price variable without having to worry about the price with tax. Thanks to byte.nl for this trick.

Aggregate Rating Scope Information

app/design/frontend/[package]/[theme]/template/review/helper/summary.phtml

The final piece to adding schema tags to a product is to include the AggregateRating information to show the basic star rating in your rich snippets. This data cannot be hidden; we’re going to update the ratings summary phtml file.  If you want to create a custom phtml for this you can do that too.

Wrap this code block in an AggregateRating scope and add the required schema information for best rating, worse rating, rating value, and the review count. Starting around Line 27…

<span itemprop=”aggregateRating” itemscope itemtype=”http://schema.org/AggregateRating”>

<?php if ($this->getReviewsCount()): ?>

<meta itemprop=”ratingValue” content=”<?php echo $this->getRatingSummary(); ?>”/>

<meta itemprop=”reviewCount” content=”<?php echo $this->getReviewsCount(); ?>” />

<meta itemprop=”bestRating” content=”100″/>

<meta itemprop=”worstRating” content=”0″/>

….

</span>

Now, lets move on to tackling the grouped products.

Setting up grouped product offers

app/design/frontend/[package]/default/template/catalog/product/view/type/grouped.phtml

As we have the base for our Product schema, adding the grouped product offers isn’t that much more work. We will just need to open up the grouped.phtml template and make a few changes.

Starting on Line 38, we have to add availability of the main product scope.

<?php if ($_product->isAvailable() && $_hasAssociatedProducts): ?>

<p class=”availability in-stock”><link itemprop=”availability” href=”http://schema.org/InStock”><?php echo $this->__(‘Availability:’) ?> <span><?php echo $this->__(‘In stock’) ?></span></p>

<?php else: ?>

<p class=”availability out-of-stock”><link itemprop=”availability” href=”http://schema.org/OutOfStock”><?php echo $this->__(‘Availability:’) ?> <span><?php echo $this->__(‘Out of stock’) ?></span></p>

<?php endif; ?>

Then, we move down to our grouped product loop. This is where we have to represent a new offer, then inside of that offer we create another product scope and link it to our main product (the item id we pointed out earlier). This is what links the product as a sub-product and gets us that pretty price range in our rich snippet. Remember to close all the tags!

Start the new scopes Line 64 and 65:

<tr itemprop=”offers” itemscope itemtype=”http://schema.org/Offer”>

<span itemscope itemtype=”http://schema.org/Product” itemref=”#product_base”>

<td itemprop=”name”><?php echo $this->htmlEscape($_item->getName()) ?></td>

The new offers on Line 69 and 70:

<td class=”a-right”>

<meta itemprop=”price” content=”<?php echo number_format($_item->getPrice(), 2);?>” />

<meta itemprop=”priceCurrency” content=”<?php echo Mage::app()->getStore()->getCurrentCurrencyCode();?>” />

And lastly, add product availability on Lines 78-85:

<?php if ($_item->isSaleable()) : ?>

<link itemprop=”availability” href=”http://schema.org/InStock”>

<input type=”text” name=”super_group[<?php echo $_item->getId() ?>]” maxlength=”12″ value=”<?php echo $_item->getQty()*1 ?>” title=”<?php echo $this->__(‘Qty’) ?>” class=”input-text qty” />

<?php else: ?>

<link itemprop=”availability” href=”http://schema.org/OutOfStock”>

<p class=”availability out-of-stock”><span><?php echo $this->__(‘Out of stock’) ?></span></p>

<?php endif; ?>

</td>

<?php endif; ?>

Remember, as we are making a new product offer we have to include the Name, Price, Availability, and Currency all over again.

 

*Updated 2020 - for Magento 2 Websites

While Magento 1 doesn’t provide in-built functionality for rich snippets, Magento 2 offers product schema by default. However, the range of fields generated is quite limited and configuration is not possible from the CMS.

Still requiring some work to get to a good quality; Magento 2 will generate a warning on “price” when tested with Google’s microdata validator. This is because by default, Magento will include a currency symbol in the price.

We often recommend it’s easiest to remove the default microdata with this free extension, before using one of the many other extensions available to easily handle and configure rich snippets in Magento 2.

However, if you wish to use the default Magento 2 schema and fix the “prices” error that will occur by default, navigate to…

/magento/module-catalog/view/base/product/price/amount/default.phtml

Find the line…

$block->getSchema() ? ' itemprop="price"' :

…and replace it with:

$block->getSchema() ? ' itemprop="price" content="' . $block->getDisplayValue() . '"':

(Ensure you validate your schema before implementing this fix, as a resolution for this issue has been promised by Magento for future releases.)

You should now find that price is formatted correctly and is able to be fully validated.

Don't forget to test!

As always, we need to test our tags to make sure that Google, Bing, Yahoo and other search engines are displaying these rich snippets properly. We would recommend periodic testing throughout the implementation process as to catch issues early.

We recommend using Google's Structured Data Testing Tool to validate schema, as if offers both the option of validating a web page or a block of code. Furthermore the tool will highlight issues, and suggest fixes for outstanding schema issues.

Going one step beyond...

While the attributes highlighted earlier are "essential", marking up other attributes can make your product pages future-proof. Google is regularly using new schema types to drive new features and functionality, so by marking these extraneous attributes up, you ensure your product pages are eligible to appear in these.

Furthermore, if you're hoping to sell your products through Google Shopping, having product schema ready on your webpages can make setting up a shopping feed quick and painless, avoiding the costs of additional modules or manual feed building.

These might include:

  • Colour.
  • Pattern.
  • Material.
  • Height.
  • Weight.
  • Width.
  • Release date.
  • Production date.

A full listing of valid product schema types can be found on schema.org. Don't hesitate to experiment and go a step beyond to provide complete and detailed schema. You may find yourself rewarded in the long run with early visibility on new Google products and features.

If you require more information please contact us at Williams Commerce.