In this article, I will explain in an easy way how to add the correct structured data to Magento for Google Shopping using Microdata or JSON-LD.
What template are you using?
First, we need to know which template you are using.
Login to the Magento Admin panel and go to System > Configuration
Under Configuration click on Design
If you have a Package only.
Then select Package and write down the current package name. For me this is rwd
If you have a Package and Theme selected.
Then select Package and write down the current package name. For me this is default
And write down the name of the theme that you are using. For me, this is cenitouch
Navigate to the file that needs editing
Open up your favorite FTP program or an IDE with FTP option.
Navigate to the following location and open the file view.phtml
Without Theme
app > design > frontend > rwd > default > template > catalog > product > view.phtml
With Theme
app > design > frontend > default > cenitouch > template > catalog > product > view.phtml
Before editing always create a backup, for example, copy the file and rename it to view.phtml.org
The below code is for English and US countries, where the decimal separator is a dot.
Add the following code to the bottom of the file view.phtml
<script type="application/ld+json"> { "@context": "http://schema.org/", "@type": "Product", "name": "<?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?>", "offers": { "@type": "Offer", "priceCurrency": "<?php echo $currency_code = Mage::app()->getStore()->getCurrentCurrencyCode(); ?>", "image" : "<?php echo $_product->getImageUrl(); ?>", "description" : "<?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?>", "url": "<?php echo $_product->getProductUrl(); ?>", <?php $specialPrice = $_product->getFinalPrice(); $normalPrice = $_product->getPrice(); if ($normalPrice != $specialPrice){ ?> "price": "<?php echo preg_replace('/[^0-9.]+/', '',strip_tags(Mage::helper('core')->currency($_product->getFinalPrice()))); ?>", <?php }else{ ?> "price": "<?php echo preg_replace('/[^0-9.]+/', '',strip_tags(Mage::helper('core')->currency($_product->getPrice()))); ?>", <?php } ?> "itemCondition" : "http://schema.org/NewCondition", <?php $microdata_stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getIsInStock(); if ($microdata_stock >= 1){ $microdata_stock_msg = 'In Stock'; }else{ $microdata_stock_msg = 'Out of Stock'; } ?> "availability" : "<?php echo $microdata_stock_msg; ?>" } } </script>
The code below is for mainland Europe where you use a comma as a decimal separator.
<script type="application/ld+json"> { "@context": "http://schema.org/", "@type": "Product", "name": "<?php echo $_helper->productAttribute($_product, $_product->getName(), 'name') ?>", "offers": { "@type": "Offer", "priceCurrency": "<?php echo $currency_code = Mage::app()->getStore()->getCurrentCurrencyCode(); ?>", "image" : "<?php echo $_product->getImageUrl(); ?>", "description" : "<?php echo $_helper->productAttribute($_product, nl2br($_product->getShortDescription()), 'short_description') ?>", "url": "<?php echo $_product->getProductUrl(); ?>", <?php $specialPrice = $_product->getFinalPrice(); $normalPrice = $_product->getPrice(); if ($normalPrice != $specialPrice){ ?> "price": "<?php echo preg_replace('/[^0-9.]+/', '',str_replace(',','.',str_replace('.','',strip_tags(Mage::helper('core')->currency($_product->getFinalPrice()))))); ?>", <?php }else{ ?> "price": "<?php echo preg_replace('/[^0-9.]+/', '',str_replace(',','.',str_replace('.','',strip_tags(Mage::helper('core')->currency($_product->getPrice()))))); ?>", <?php } ?> "itemCondition" : "http://schema.org/NewCondition", <?php $microdata_stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getIsInStock(); if ($microdata_stock >= 1){ $microdata_stock_msg = 'In Stock'; }else{ $microdata_stock_msg = 'Out of Stock'; } ?> "availability" : "<?php echo $microdata_stock_msg; ?>" } } </script>
Save the file and check if the product landing page has no errors.
Important
If you have existing schema data, you need to either delete the old schema data or copy elements you need from the code above into your existing schema. If you don’t do this, then Google will see two product listings, resulting in errors.
Checking The Results
You can use Google’s Structured data testing tool, to check if everything is done correctly. The below image shows an example of a correct listing.
Copy your landing page link (address bar URL) and paste it in the field for fetching the URL.
When you have warnings in your diagnostics tab, remember that it takes up to 30 days before they will disappear, this is because Google does not crawl your landing pages every day but in 30 days.
Hi Emmanuel, Thanks very much for this excellent guide, it has really given me a much better understanding of what I need to do. I have existing schema markup built in to the theme but it doesn’t include itemCondition and I’m getting errors in the merchant centre.I know I need to add the condition element but we have a mixture of new, used and refurbished products. We have a “condition” attribute but I’m not sure how to pull the contents of this for each product. Any help would be greatly appreciated.Thanks in advance,Sean
Hello Sean, I’m guessing as this is not a default option within Magento, that your using custom options? If so then please contact [email protected]
Thank you so much for posting this ! I’m totally not technical here, but I put that code in my site and when I test it with the Structured data testing tool- it does seem to be working! AND it looks like it works for all the products on my website!So my next question is- how do I get Image, Product Description and URL data for my products into the structured data? Is there some code I can add to this snippet that will incorporate those attributes as well? I tried to add them on the individual product page but google thinks its a second product, as you mentioned in your article.
Hi Criss, thanks for the kind words. I have updated the article to add image, short description and url. Hope it helps.
Perfect! Thanks Emmanuel!
Hi,
Still getting error, you have helped me out in passed but suddenly its giving the same error again, I am afraid that it may be linked with my change in hosting service provider (Definitely Not sure as I recognised after one or two months) here is the url https://radiumbox.com/shop/startek-fm220-single-fingerprint-biometric-usb-scanner.html
Kindly revert with the solution please.
Hello Ravi, I can not see any errors, thus can not solve the problem. I can help you privately, please email me [email protected].
Well done, Thanks again for your prompt support on behalf of Team radiumbox
Thanks a lot man. Just had to use this code for getting prices with tax included:
Mage::helper(‘tax’)->getPrice($_product, $_product->getFinalPrice());
Cheers
Glad this worked out for you.
Hi, Your blog is so useful, I am not technically sound but manage my website by own, I have added but getting an error. Please help.
Url – https://radiumbox.com/shop/feitian-epass-2003-auto-usb-token.html
Price – (The property .299.00 is not a valid price specification. Find out more about
So the script allows a dot in the price, because you will have prices such as 299.00
You will need to remove the dot after Rs This will than show the price as 299.00 instead of .299.00
Hope it helps
Thanks Emman, Superb Fantastic and on time. Really thankful. In leisure I will need some more suggestion from you, like comma in price and description for SEO. Thanks Again
Thanks for posting this , But how can we implement for sale price …
Hello Mahesh, I have updated the code to reflect this.
I’m getting a return from itemprop price with no decimal between the dollars and cents, currency specifies just fine tho. Any suggestions?
Try the following, in the preg_replace replace the ‘/D+/’ with ‘^[+-]?[0-9]{1,3}(?:,?[0-9]{3})*(?:.[0-9]{2})?$’
I’m getting an error when I run the code through Google Structured data testing:
currency($_product->getPrice())); ?> (The property currency($_product->getPrice())); ?> is not a valid price specification.
You need to test the landing page URL not the code.
does this work for grouped products as well as simple products?
This code is specifically designed for Google Shopping. Which if you use variables need to modify the code so that landing page pre selected product data is the same as the microdata. You will need know how your products are sent to Google Shopping first to know what you need to do on the landing page. If you only send your main product to Google Shopping, than only show that product in the micro data. Hope it helps.
No i send the individual simple products in the shopping feed using a title of parent name, child name and use the parent description/image. The parent product is just a landing page. So how would i configure?
You need to submit the product url of the individual product instead of the main product.