Category Archives: Uncategorized

Schema.org: Product Variants with Different Prices

In my last post, I argued that Google is increasingly able to handle multiple product / offer entities in product pages and still generate Rich Snippets for products. Some people have pointed out that the markup in the live pages I cited was misleading, because it “abused” the http://schema.org/offers property and wrongly puts the multiple offers / products into a http://schema.org/SearchResultsPage entity as a container. While I stick to my original prediction that Google will increasingly select or summarize multiple entities from a page to generate Rich Snippets customized to a single query, I want to provide a clean approach for this frequent scenario.

Below, I will explain how you can properly model a product detail page with multiple product variants that have different prices in a way that almost certainly triggers Google Rich Snippets for products.

The main challenge is to get a price range shown in a Rich Snippet for a page with multiple product variants, like so:

Google Rich Snippet for multiple cars

Before we start, it is important to understand that, to my knowledge, Google has previously shown price ranges in Rich Snippets for Products only in one of the following three cases:

  1. For http://schema.org/AggregateOffer, like so:
    {
      "@context": "http://schema.org",
      "@type": "Product",
      "image": "dell-30in-lcd.jpg",
      "name": "Dell UltraSharp 30\" LCD Monitor",
      "offers": {
        "@type": "AggregateOffer",
        "highPrice": "$1495",
        "lowPrice": "$1250",
        "offerCount": "8",
        "offers": [
          {
            "@type": "Offer",
            "url": "save-a-lot-monitors.com/dell-30.html"
          },
          {
            "@type": "Offer",
            "url": "jondoe-gadgets.com/dell-30.html"
          }
        ]
      }
    }
    
  2. For GoodRelations price specifications in RDFa syntax using gr:hasMinCurrencyValue / gr:hasMaxCurrencyValue, like so:
    <div typeof="gr:Offering" about="#offer">
      <div property="gr:name">GoodRelations T-Shirt - Various Designs</div>
      <div rel="gr:hasBusinessFunction" 
         resource="http://purl.org/goodrelations/v1#Sell"></div>
      <div rel="gr:hasPriceSpecification">
        <div typeof="gr:UnitPriceSpecification">Price: 
        <div property="gr:hasCurrency" content="USD">$</div>
        <span property="gr:hasMinCurrencyValue">10.00</span> to $
        <span property="gr:hasMaxCurrencyValue">99.99</span>
        <div property="gr:validThrough" datatype="xsd:dateTime" content="2012-11-30T23:59:59Z"></div> 
      </div>
    </div>
    
  3. For multiple http://schema.org/Offer entities linked to the same product via http://schema.org/offers, like so:
    {
      "@context": "http://schema.org",
      "@type": "Product",
      "image": "dell-30in-lcd.jpg",
      "name": "Dell UltraSharp 30\" LCD Monitor",
      "offers": [
    	{
    		"@type" : "Offer",
    		"price" : "35",
    		"priceCurrency" : "EUR"
    	},
    	{
    		"@type" : "Offer",
    		"price" : "55",
    		"priceCurrency" : "EUR"
    	}
    	]
    }
    

So far, there was no documented markup pattern for Web pages with multiple product variants that have differing prices. Still, there is a straightforward way to achieve this by combining

Before we start, remember that there are two alternative approaches for modeling product and offer information in schema.org:

  1. You can start with the http://schema.org/Product entity and link it to one or more http://schema.org/Offer entities via http://schema.org/offers.
  2. Or you can start with a http://schema.org/Offer entity and link to the http://schema.org/Product included via http://schema.org/itemOffered.

The essential trick is to use both in combination, which is perfectly valid from the underlying GoodRelations model in schema.org:

  1. First, model an abstract version of the product, e.g. omitting size, color, or configuration information, as a http://schema.org/Product.
  2. Then, link this to two or more http://schema.org/Offer entities via http://schema.org/offers.
  3. Finally, link each of these offers to a more detailed product entity via http://schema.org/itemOffered.
    1. Here is a complete example:

      {
      	"@context" : "http://schema.org",
      	"@type" : "Product",
          "description" : "The Hepp Smart Watch is a unique wristwatch.",
          "name" : "Hepp Smart Watch",
      	"offers" : [
      		{
      			"@type" : "Offer",
      			"availability" : "http://schema.org/InStock",
      			"price" : "50",
      			"priceCurrency" : "EUR",
      			"itemCondition": "http://schema.org/NewCondition",
      			"itemOffered" : 
      			{
      				"@type" : "Product",
      		        "description" : "The Hepp Smart Watch in Silver is robust and has enough memory for most tasks.",
      		        "name" : "Hepp Smart Watch in Silver with 16 GB RAM"
      			}
      		},
      		{
      			"@type" : "Offer",
      			"availability" : "http://schema.org/InStock",
      			"price" : "400",
      			"priceCurrency" : "EUR",
      			"itemCondition": "http://schema.org/NewCondition",
      			"itemOffered" : 
      			{
      				"@type" : "Product",
      		        "description" : "The best Hepp Smart Watch ever: Gold-plated and with 64 GB.",
      		        "name" : "Hepp Smart Watch in Gold with 64 GB RAM"
      			}
      		}
      	]
      }
      

      I have not seen this in the wild yet, but I am very confident that it is the best approach for pages with multiple product variants.

Google Product Rich Snippets for Multiple Products on a Page

It has been a strong principle of Google to show Rich Snippets for Products only if there is exactly one single product on the page. For quite a while, we have predicted that Rich Snippets will become a much more dynamic feature in Google, e.g. that it will be turned on an off depending on a particular query and depending on how it helps highlight important information in the SERPs. Now, for a few weeks, there has been a conflicting requirement for developers in the Google Developer documentation: At https://developers.google.com/structured-data/rich-snippets/products, Google says

Product markup should be used for a specific product, not a category of products or a list of products.

while at https://developers.google.com/structured-data/policies, they state that all products in a multi-product page are to be marked up (or none):

Each entity should be marked up using the relevant schema.org type, such as schema.org/Product for product category pages. Marking up just one category entity from all listed on the page is against our guidelines.

It essentially meant that you could mark-up only deep detail pages that describe exactly one single product. Today, we found first evidence that Google is now properly summarizing multiple product descriptions to generate a summary. If you search for “New Volkswagen Golf Yorkville New York”, you might get the following search result:

Google Rich Snippet for multiple cars

If you look at the first result, you see a price range ($21,515.00 to $30,830.00):

Google Rich Snippet for multiple cars

Now, contrary to what one would expect, there is no http://schema.org/AggregateOffer in the markup, but simply seven http://schema.org/Offer entities. $21,515 is the lowest value of all price properties, and $30,830 the highest one.

While we have not yet seen it in the wild, we expect that Google will also try to create Rich Snippets for single products from multi-item pages depending on the user query. So instead of summarizing a multi-product page into one aggregate Rich Snippet, they might chose a single entity that they think fits your information needs best.

In short: We see that we can now safely mark-up multiple products in a page and expect Rich Snippets for price information. Google is able to summarize them. That is good news, in particular for automotive Web sites.

PS: If you are the person responsible for adding the schema.org markup to http://www.steetpontevolkswagen.net/, I would first like to congratulate to the pretty advanced and effective use of schema.org. Second, I would recommend that you add the new features for http://schema.org/Car for standardized car features and to use http://schema.org/additionalProperty for the other car features.. Need help? Contact us!

PPS: If you look deeper into the markup, you will see that the actual data structure is even a bit weird, because the main entity is a http://schema.org/SearchResultsPage type, linked to the seven offers via http://schema.org/offers. This is wrong, because the offers property for a http://schema.org/SearchResultsPage type is inherited from http://schema.org/CreativeWork and links to offers of the creative work. But the site owner is likely not offering the search results page for $ 20,000 ;-).

Semantic SEO: What is the difference between schema.org and Microdata?

Often, developers being new to schema.org and the usage of semantic SEO techniques are confused about the relationship between schema.org and Microdata, Microformats, RDFa, GoodRelations, and other standards.

Here is a quick explanation that I have been given so often that I assume it may be useful for others:

When you expose structured data from within Web content by adding extra markup to HTML content, you have essentially two components:

1. A vocabulary (also known as data schema, ontology, data dictionary, depending on the background of the people you speak to): This provides global identifiers for types of things (“Product”, “Car”, “Restaurant” – often called “classes” or “types”) and for properties (e.g. “screen size”, “weight” – often called properties or attributes)

2. A syntax for publishing the data within Web pages in HTML. The syntax is the convention for the actual characters used to publish a piece of data. Relevant syntaxes in here are RDFa, Microdata, and recently JSON/JSON-LD.

Popular vocabularies on the Web are schema.org, GoodRelations, FOAF, SIOC, and a few others.

At Web scale, the absolutely dominant vocabulary for mainstream search engines is schema.org. GoodRelations is a special case, since 99% of the GoodRelations vocabulary are now integrated in schema.org, so you do not have to choose between the two. In other words, schema.org is now a new namespace for using GoodRelations. Additional vocabularies may have relevance on the long tail and can typically be used in addition to schema.org with no negative effect. Once they will have gained sufficient popularity, search engines may care.

Now, you can use the same vocabulary in multiple syntaxes. For instance, you can publish schema.org in RDFa or Microdata or JSON/JSON-LD. The most appropriate syntax depends on the purpose and on the target applications of your data. In Web content, Microdata and RDFa should be equally well supported by search engines in theory. However, actual support varies.

As of now, I would recommend the following:

1. Microdata syntax for schema.org. RDFa works, but not all structural variants of the same data will be understood by search engines and you need to be a real expert to find out which ones work and which ones don’t.

2. RDFa for GoodRelations in the original namespace, since for historic reasons, search engines know well how to process it.

3. JSON-LD for schema.org in eMails and other upcoming scenarios, see also https://developers.google.com/gmail/actions/reference/formats/json-ld.

Microformats are a special case, since they combine syntax and vocabulary. For very simple data structures, this works well, and Microformats are widely understood by search engines. It is just my personal opinion, and I am sure advocates of Microformats will see things differently, but in the light of schema.org and generic syntaxes like Microdata, RDFa, and JSON-LD, Microformats will be limited to very basic usages, and likely fade out.

So in a nutshell, schema.org in Microdata is currently the most widely understood and recommended variant.

schema.org in RDFa and in particular JSON-LD may become more important in the future, but you will have to monitor closely to which degree search engines can actually process data in those syntaxes.

JSON-LD: Finally, Google Honors Invisible Data for SEO

For quite a while, I have been arguing that RDFa as a syntax for structured data in Web content is problematic when it comes to exposing more granular data than just a few property names. While many advocates of RDFa stressed that reusing the exact same visible elements for structured data markup, as in this example

<body> 
<div property="vcard:tel">+49-89-1234-0</div> 
</body>

was beneficial because it reduces redundancy, it also raises complexity for developers, since you violate the principle of “separation of concerns” – you have to align a given HTML tree structure with a given data structure, dictated by the vocabulary, like schema.org or GoodRelations.

As a consequence, I once developed and promoted the “RDFa in Snippets Style” approach, where the RDFa markup would reside in blocks of invisible <div> or <span> elements, like this:

<body> 
<!-- Content for humans --> 
<div>+49-89-1234-0</div> 
<!-- RDFa rich meta-data --> 
<div property="vcard:tel" content="+49-89-1234-0"/> 
</div> 
</body>

This has been a big success – most of the GoodRelations extensions for shop software, running on at least 20,000 Web shops globally, use that approach and get their content honored by Google.

Now, one caveat has always been that Google indicated that invisible markup, i.e. RDFa elements that do not reuse visible content, would not be honored. The likely rationale for that guideline was that

  1. invisible markup invites spammers that try to manipulate the search engine,
  2. a link to human-readable content allows to combine the structured data and the textual content for information extraction heuristics, and
  3. the data quality is likely higher for visible content (since humans will complain otherwise).

Now, in silence, RDFa in “Snippet Style” (and similar patterns in Microdata) have for long been accepted by Google, as long as other quality indicators for the site were positive. But there was always a doubt, which was bad, since the development effort for weaving in advanced data markup in RDFa or Microdata syntax into HTML templates in a form that combined visible content elements with data markup was, in my experience, 5 – 10 times higher as compared to using RDFa in “Snippet Style”.

The bigs news is that this uncertainty is going away, since Google now openly moves to accepting data markup in JSON-LD syntax not tied to visual elements.

Of course, this is just a first signal, but I personally think that in the future, we will see JSON-LD in script elements for all advanced data markup, and RDFa and Microdata only for the very simple use-cases.

That is a good sign towards a broader use of data markup for e-commerce, for sure.

Web Site Relaunch

Today, we finally released the complete update of our corporate Web site at http://www.heppresearch.com. While our main line of business is individual consulting with a selected number of clients, we thought it was high time to update our face to the public to the 2012 state of the art of Web development. After all, we claim to know how to do marketing in the next generation of the WWW, so we should show that we easily master the current one.

A key goal of the release was to support responsive design so that the page would work beautifully on any device, from a smartphone to my 30 inch screen in the office, and to migrate to HTML5.

I hope you like our new design as much as I do. Any feedback will be very much appreciated.

The new Hepp Research Web page

The new, responsive HTML5 Web design

.