Either "offers", "review", or "aggregateRating" should be specified - Google Error

Shopify Partner
2567 39 586

I was asked to help with the same problem.

Here is my analysis (no solution so far)

 

The shop uses Shopify product reviews App, small inventory, small number of reviews.

Review App integrated in a usual way:

<div id="shopify-product-reviews" data-id="{{product.id}}">
  {{ product.metafields.spr.reviews }}
</div>

This evaluates to the following HTML served to visitors:
output 1)

<div class="spr-header">
    <h2 class="spr-header-title">Customer Reviews</h2>
<div class="spr-summary" itemscope itemprop="aggregateRating" itemtype="http://schema.org/AggregateRating"> <meta itemprop="itemreviewed" content="Birds Earrings"> <span class="spr-starrating spr-summary-starrating"> <meta itemprop="bestRating" content="5"> <meta itemprop="worstRating" content="1"> <meta itemprop="reviewCount" content="4"> <meta itemprop="ratingValue" content="5.0">

When you run google Structured Data Testing Tool it gets this HTML, parses it and finds no errors.

However, in your browser Shopify Product Reviews App replaces this code with the following:
output 2)

<div class="spr-header">
    <h2 class="spr-header-title">Customer Reviews</h2>
<div class="spr-summary" itemscope="" itemprop="aggregateRating" itemtype="http://schema.org/AggregateRating"> <div itemprop="itemReviewed" itemscope="" itemtype="http://schema.org/Product"> <meta itemprop="name" content="Birds Earrings"> </div> <span class="spr-starrating spr-summary-starrating"> <meta itemprop="bestRating" content="5"> <meta itemprop="worstRating" content="1"> <meta itemprop="reviewCount" content="4"> <meta itemprop="ratingValue" content="5.0">

Note the change in itemreviewed property from:

 <meta itemprop="itemreviewed" content="Birds Earrings">

to:

 <div itemprop="itemReviewed" itemscope="" itemtype="http://schema.org/Product">
     <meta itemprop="name" content="Birds Earrings">
 </div>

When Google Bot retrieves the page, it does run JavaScripts and it actually sees the different result compared with what Structured Data Testing Tool sees. If you manage to get this resulting code from your browser and paste it as a code snippet into a SDTT, it produces an error too! This explains why  SDTT does not help with this test.

 

Now, here is how I see this -- the code I marked in bold defines a new property  for the aggregateRating "object".

In the output 1) this property has no type specified, and SDTT is ok with it -- it assign it type "thing"  (though Search console may not like it).

In the output 2), this property is defined as having type "Product" which only has "name" property and this does not pass the check, therefore the error message "One of offers or review or aggregateRating should be provided."

 

As far as I understand, this itemReviewed property is not necessary if aggregateRating is nested inside the Product, this would be the best option in my opinion (at least SDTT is ok with this).

 

Now, if you have a product which has not received review for some time, your metafield will contain something similar to my first snippet. However, if new review is added, your metafielded  will be updated to look like output 2) and will fail straight away in SDTT too.

Relevant discussion at Google webmasters

 

 

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
0 Likes
Tourist
5 0 0

I guess I'll throw my name in as having the same problems as everyone else here. 

I contacted support a couple of days ago and will let you know the response.

 

I have 17 products with the "either" error. The first linked product has the problem, the second linked product does not. The only difference being the first link was last reviewed mid October and the second link was last reviewed mid September.

 

https://www.engleberts.com/collections/wood-sunglasses/products/sandalwood-sunglasses

 

https://www.engleberts.com/collections/wood-sunglasses/products/zebrawood-sunglasses

 

So we have one poster that suggest waiting until you get another review since the supposed Shopify fix and another user says a new review will set your product up for fail. 

 

Don't mind saying I'm  a little bit frustrated and confused. I'll let you know what Shopify comes up with for me.

 

0 Likes
Shopify Partner
2567 39 586

Mate, here are the code snippets from your product pages:

good one:

<meta itemprop="itemReviewed" content="Zebrawood Sunglasses, Stars and Bars, Polarized">

bad one:

<div itemprop='itemReviewed' itemscope itemtype="http://schema.org/Product">
   <meta itemprop="name" content="Real Sandalwood Sunglasses, Ice Blue Polarized Lenses, Club Style">
</div>

Pretty  much matches my pattern...

 

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
0 Likes
Shopify Partner
2567 39 586

To further support my diagnosis in previous message:

for affected products Search console reports: "2 items detected: Some are invalid", which means the itemReviewed  is considered a separate product.

 

My solution is to not output the itemReviewed at all, provided that shopify review code is nested inside the main Product element.

Usually Shopify product reviews are included as follows:

 

<div id="shopify-product-reviews" data-id="{{product.id}}">
    {{ product.metafields.spr.reviews }}
</div>

Here is the code I've used instead:

 

<div id="shopify-product-reviews" data-id="{{product.id}}">
{% assign mf = product.metafields.spr.reviews | newline_to_br | split: "<br />" %}
{% for line in mf %}
   {% if line contains "meta" and line contains "itemreviewed" %}
   {% elsif line contains "div" and line contains "http://schema.org/Product" %}
     {% assign skip_div = true %}
   {% elsif skip_div %}
     {% if line contains "/div" %}
       {% assign skip_div = false %}
     {% endif %}
   {% else %}
      {{ line }} 
   {% endif-%}
{% endfor %}
</div>
<script>
  var SPRCallbacks = {
    onProductLoad: function( e ) {
      $('[itemprop="itemreviewed"]').remove();
      $('[itemprop="itemReviewed"]').remove();  
    }
  }                
</script>

What it does: the liquid code inside <div>  outputs the metafield, but removes the following elements:

<meta itemprop="itemreviewed" content="***">

and 

<div itemprop="itemReviewed" itemscope="" itemtype="http://schema.org/Product">
<meta itemprop="name" content="***"> </div>

Script part register a callback with the Shopify Product Reviews App to remove the same elements after they are output by the App.

 

This resulting HTML validates both in Structured Data Testing Tool and Search console. Note that Search console somehow does not see the updated page in "Live Test" if you've tried "Live Test" against the old code -- some caching issue.

 

I must warn that the liquid part of the solution is hackish and is a workaround until it's fixed in the App --  it's definitely better to force Shopify to properly fix this in App.

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
2 Likes
Tourist
6 0 0

@Akshay_1996 I have sent you an email. Cheers!

0 Likes
New Member
3 0 0
New Member
1 0 0

Hi tim - just dropped you an email regarding this, we're looking for a bit of support in trying to resolve the issue on our store. Is this something you could help with?

0 Likes
Shopify Partner
189 13 21

@McGreals 

Please check the revert back mail.

Thanks & Regards
Akshay Vaghasiya

Shopify Expert | E-commerce Consultant
Email: akshayvaghasiya84@gmail.com
Skype: akshayvaghasiya84
 - Want to modify or custom changes on store hire me .
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
1 Like
Shopify Partner
189 13 21

@Matt1121 

I have tested your link and I found there are few errors can be solved by implementing a new code. Only review error https://prnt.sc/psrk8h not possible to fix it because it store in the app server and it is not required for SEO because google only shows product name, description, and rating.

If you want to fix other error then let me know. I am not available on the forum then you can contact me on my email.

Thanks & Regards
Akshay Vaghasiya

Shopify Expert | E-commerce Consultant
Email: akshayvaghasiya84@gmail.com
Skype: akshayvaghasiya84
 - Want to modify or custom changes on store hire me .
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
0 Likes
Shopify Partner
2567 39 586

On a different Shop running StampedIO App, Javascript part of my solution above does not work because StampedIO recklessly overwrites the value of the SPRCallbacks variable, and while SDTT will be ok, searchbot would not be happy with the result.

 

There is a way to fix it, still in testing stage. 

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
0 Likes