Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete implementation of schema.org Structured Data #1414

Closed
fthobe opened this issue Dec 25, 2018 · 13 comments
Closed

Complete implementation of schema.org Structured Data #1414

fthobe opened this issue Dec 25, 2018 · 13 comments

Comments

@fthobe
Copy link

fthobe commented Dec 25, 2018

Expected behavior

Cornerstone pages of all types (Products, Categories, Blog and Content) should contain Schema.org validation to enable all possible features of google search engine result pages. Currently breadcrumbs fail and product information are incomplete.

Actual behavior

Breadcrumbs

  • Item is missing

Product

  • Currency is missing
  • URL is missing

Steps to reproduce behavior

Knock yourself out with Google's amazing Structured Data Testing Tool
https://search.google.com/structured-data/testing-tool#url=http%3A%2F%2Fcornerstone-light-demo.mybigcommerce.com%2Fall%2Fcanvas-laundry-cart%2F

@carsonreinke
Copy link
Contributor

Related to #1403.

@Tiggerito
Copy link
Contributor

If you check the SDTT now you will see a lot more warnings added, with Google asking people to fill in more fields like gtin.

In my experience most themes (so probably Cornerstone) get the markup wrong. I often see invalid values when there are no reviews and invalid itemCondition values.

I personally remove all microdata added by a theme and add my own json-ld

@fthobe
Copy link
Author

fthobe commented Jan 22, 2019

@Tiggerito Would you mind sharing your json-ld implementation of cornerstone?

@Tiggerito
Copy link
Contributor

Tiggerito commented Jan 23, 2019

We don't implement it in the theme as we are not theme developers. We place our code in FooterScripts so that it does not get removed on theme updates.

I have to be careful what I share, as this is how we make a living. Here's an example of our breadcrumbs code. Not sure how to format it correctly:

{{#gt (length breadcrumbs) 1}}

<script type="application/ld+json" id="wsa-schema-breadcrumbs"> { "@context": "http://schema.org", "@type": "BreadcrumbList", "@id": "#BreadcrumbList", "itemListElement": [ {{#each breadcrumbs}} {{#unless @last}} {{#unless @FIRST}},{{/unless}} { "@type": "ListItem", "position": {{add @Index 1}}, "item": { "@id": "{{{concat url '#Breadcrumb'}}}", "name": {{{json name}}} } } {{/unless}} {{/each}} ] } </script>

{{/gt}}

@fthobe
Copy link
Author

fthobe commented Mar 7, 2019

hey @Tiggerito ,

Please find below the correct consolidated schema.org implementation in json format. We have skipped non obligatory values and tried to find a away that works for everybody.

We are working on some improvements to cover some additional use cases:

  • implement min and max price with a condition
  • we are still considering integrating also related objects

Breadcrumbs are next on the list.

Maybe @Ubersmake can make a commit to the code base we can work on by also removing exisiting schema.org implementations.

Fabian

<script type="application/ld+json">
    {
        "@context": "http://schema.org",
        "@type": "Product", 
        "name": "{{product.title}}", 
        "image": "{{getImage product.main_image 'product_size' (cdn theme_settings.default_image_product)}}", 
        "brand": {
            "@type": "Thing", 
            "name": "{{product.brand.name}}", 
            "url": "{{product.brand.url}}"
        },
        "description": "{{{product.description}}}", 
        "sku": "{{product.sku}}",
        "url": "{{product.url}}",
        "offers": [{
                "@type": "AggregateOffer",
                "highPrice": "{{product.price.price_range.max.with_tax.value}}",
                "lowPrice": "{{product.price.price_range.min.with_tax.value}}", 
                "priceCurrency": "{{currency_selector.active_currency_code}}"
            },
            {
                "@type": "Offer", 
                "price": "{{product.price.with_tax.value}}",
                "priceCurrency": "{{currency_selector.active_currency_code}}", 
                {{#if product.out_of_stock}}
                    "availability": "http://schema.org/OutOfStock",
                {{else}}
                    "availability": "http://schema.org/InStock",
                {{/if}}
                "condition": "{{product.condition}}", 
                "url": "{{product.url}}",
                "priceSpecification":{
                    "@type": "PriceSpecification", 
                    "maxPrice": "{{product.price.price_range.max.with_tax.formatted}}",
                    "minPrice": "{{product.price.price_range.min.with_tax.formatted}}", 
                    "valueAddedTaxIncluded": "True"
                }
            }
        ] 
        {{#if product.num_reviews '>' 0}}
        ,
        "aggregateRating": {
            "@type": "AggregateRating",
            "ratingValue": "{{product.rating}}",
            "ratingCount": "{{product.num_reviews}}",
            "reviewCount": "{{product.num_reviews}}"
        }, 
         "review": [
             {{#each product.reviews.list}}
             {{#if @index '>' 0}} , {{/if}}
                {
                  "@type": "Review",
                  "datePublished": "{{date}}",
                  "name": "{{title}}",
                  "description": "{{text}}",
                  "author": "{{name}}",
                  "reviewRating": {
                        "@type": "Rating",
                        "ratingValue": "{{rating}}"
                    }, 
                    "itemReviewed": {
                        "@type": "thing", 
                        "name": "{{../../product.title}}"
                    }
                }
            {{/each}}
            ]
        {{/if}}
    }

@Tiggerito
Copy link
Contributor

Hi,

I'm currently working on an app that removes all existing structured data and adds our own (json-ld). We will provide people with extra options in configuring what and how things are marked up.

I think it would be hard to have a one size fits all solution like this. And it can be hard to make sure a solution has no bugs. e.g. your description will break in some cases due to poor character encoding. As I find these issues my Handlebars code has got more complex!

Googles new warnings and errors mean that some store owners will not be happy without having very complete markup. And future requirements will happen. The current productID warning is already a requirement for Facebook and may soon be one for the Google Merchant Centre (My speculation). Same goes for including gtin etc.

Entities like an Organization can vary a lot and can include information not available from the available objects and data. A simple issue is getting the business phone number in a valid international format. Or marking it up as a LocalBusiness if they have a physical store. This is something our app will be able to do but is not possible with the data available, Handlebars and built in theme code.

To aid in making this flexible, I suggest all marked up entities are given unique ids. This gives us the opportunity to merge separate clumps of json-ld into the same entities. e.g. for product we include:

"@id": "{{{concat product.url '#Product'}}}",

Note the use of a hash value to uniquely identify this as a Product on the product page.

This means 3rd party developers can augment existing entities, add extra properties etc. A common issue we face is that review systems add their own Product that does not merge with the themes product. Causing two incomplete entities. The use of ids fixes that.

Other entities we use are like this:

"@id": "{{{concat urls.home '#WebSite'}}}",
"@id": "{{{concat urls.home '#Organization'}}}",
"@id": "{{{concat url '#Breadcrumb'}}}",

etc.

I'd also love the ability to have a theme easily exclude all structured data. Our JavaScript solution to remove it is a bit of a hack and has issues. I've seen some json-ld based themes where the structured data is in its own set of files that can be easily excluded from the header by commenting out one line. Even better if it can be a setting.

Another way to help developers is to give the scripts unique ids. That way people can detect if a script is present and even remove it:

<script type="application/ld+json" id="schema-product"> I use that to make sure my schema remover does not remove our own code.

@fthobe
Copy link
Author

fthobe commented Mar 27, 2019

Hi @Tiggerito, it seems like @carsonreinke doesn't show us much love!!!

@ghost
Copy link

ghost commented Apr 19, 2019

@fthobe we fixed the breadcrumbs issue that caused validation error (#1403)
Using the provided Structured Data Testing Tool it seems like there are no errors.
Are you still experience this issue?

@carsonreinke
Copy link
Contributor

@fthobe LOL, did I say something?

@Tiggerito
Copy link
Contributor

Tiggerito commented Apr 19, 2019

Jono Alderson and Yoast SEO have just come out with a schema specification to deal with the issue of properly integrating and linking entities in structured data. Especially when multiple parties are involved with adding Structured Data.

https://developer.yoast.com/schema-documentation/specification/

You'll notice the cornerstone of their solution is also using IDs and # values.

Note that I personally don't recommend using @graph at this time, as Bing and maybe other systems don't support it.

Their solution also provides a way to switch off SD entities, hook into them and edit them, or remove them entirely.

@Tiggerito
Copy link
Contributor

The new BreadcrumbList microdata looks valid. Note that the final crumb uses the current page URL as the id. If you use the current page as the id on other entities, like the product, things will clash.

@carsonreinke
Copy link
Contributor

@Tiggerito don't you mean JSON-LD and Microdata and not OpenGraph?

@Tiggerito
Copy link
Contributor

Not OpenGraph. @graph is part of json-ld but not supported by Bing. It's a way to specify multiple top level entities in a single script.

@mattolson mattolson changed the title Correct implementation of schema.org Structured Data Complete implementation of schema.org Structured Data May 7, 2019
@ghost ghost added the feature request label May 7, 2019
@ghost ghost closed this as completed Aug 14, 2019
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants