Automating Schema Structured Data on Sitebulb.com | Sitebulb
Automating Schema Structured Data on Sitebulb.com
Patrick Hathaway
Updated March 4, 2021
This article is a case study of our approach to automating a site-wide structured data implementation for our own website, sitebulb.com.
I decided to document the process, so I hope it is useful to some people out there who need to do something similar.
Our site is built using the open source .NET CMS, Umbraco. While there are some off-the-shelf structured data plugins, none of them looked particularly comprehensive, so we decided to work directly with our own developer instead, to build a custom solution.
What on earth is this post about and who is it for?
I anticipate that this post might be useful to anyone in a similar position to us, needing to work directly with developers to (at least mostly) automate the addition of structured data to every page on a website. Hopefully some of the thought processes and methodologies we used might also work for you.
This post assumes a fair amount already;
- You know what structured data is, and understand the value of adding schema markup to your pages.
- You are familiar with the methodology required for adding structured data markup to webpages.
- You are comfortable with schema.org markup and validation techniques.
Table of contents
This guide covers everything from our initial experimentation to our site-wide rollout, so there's a lot to get through.
You can jump to a specific area of the guide using the jumplinks below:
- Starting with experimentation
- Mapping out templates
- Examples for page templates
- Homepage - Schema code example
- About page - Schema code example
- Author pages - Schema code example
- Documentation pages - Schema code example
- Guides pages - Schema code example
- Manual implementation
- Developer notes
- Conclusion
Starting with experimentation
Before implementing a site-wide solution, we wanted to experiment first, by manually adding structured data to specific pages, one at a time.
Depending on your level of experience, you may not need to do this step. For us, it acted as a useful training ground where we could practice writing markup and exploring what options could work on our pages, and what the practical implementation actually looked like.
We had already decided to use JSON-LD to markup our structured data, as this allowed us to simply add a 'block' of structured data markup to a page, without worrying about trying to inline Microdata with existing HTML elements on the page. It is also the format recommended by Google, so we didn't think too hard about this decision.
To start off, we simply asked our developer to build a simple custom 'data' field into all the page templates in our CMS, which would allow us to place a JSON-LD script in the
;This is pretty much the simplest implementation method we could come up with, as it was an easy job for our developer and gave us the flexibility to experiment (an alternative would be to insert your markup via Google Tag Manager).
In our case, myself and Geoff both experimented with different [structured data markup generators](/content/resources/guides/automating-structured-data-on-sitebulbcom/# "Schema Markup Generators for Structured Data"/index.html), depending on what type of thing we wanted to achieve. This is such a straightforward way to become familiar with how the code is built up, and what sort of data you need for each property.
At this stage, we found it helpful to work with pretty-printed code, so we could better visualise the hierarchical relationships between entities and properties.
One of the benefits of this methodology is that you can visually inspect the page via View Source and manually check your code.
Always be validating
One of the goals of this training phase is an iteration through validation and improvement as you test things out.
Although the markup generators are a brilliant starting point, they are often limited in terms of the properties they allow you to include, and typically only deal with one entity at a time. As soon as you want to add extra, optional, properties, or want to start nesting different entities, you're going to need to get hands on with the code.
If you need some help getting to grips with the markup, I highly recommend this Moz post: An SEO’s Guide to Writing Structured Data (JSON-LD)
Once you get to a point where you have written and edited the JSON-LD, you need to validate it for errors or issues. Fortunately, Sitebulb has a built-in structured data validator:
Moving beyond generators
As I mentioned above, beyond the most simple implementations, we found we wanted a bit more than what markup generators could provide.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"mainEntityOfPage": {
"@type": "WebPage",
"url": "https://sitebulb.com/guides/great-guide/"
},
"headline": "A really really great guide",
"description": "A magnificent guide to all things great",
"image": "https://sitebulb.com/images/great-guide.png",
"author": {
"@type": "Person",
"name": "Patrick Hathaway"
},
"publisher": {
"@type": "Organization",
"name": "Sitebulb",
"logo": {
"@type": "ImageObject",
"url": "https://sitebulb.com/images/icon.png"
}
},
"datePublished": "2020-11-13"
}
Following my research on the value of node identifiers for structured data, I also wanted to add in @id s for each entity. Manually adding them in transforms the code to:
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"@id": "https://sitebulb.com/guides/great-guide/#blogposting",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://sitebulb.com/guides/great-guide/#webpage",
"url": "https://sitebulb.com/guides/great-guide/"
},
"headline": "A really really great guide",
"description": "A magnificent guide to all things great",
"image": "https://sitebulb.com/images/great-guide.png",
"author": {
"@type": "Person",
"@id": "https://sitebulb.com/authors/patrick-hathaway/#person",
"name": "Patrick Hathaway"
},
"publisher": {
"@type": "Organization",
"@id" : "https://sitebulb.com/about/#organization",
"name": "Sitebulb",
"logo": {
"@type": "ImageObject",
"@id":"https://sitebulb.com/#logo",
"url": "https://sitebulb.com/images/icon.png"
}
},
"datePublished": "2020-11-13"
}
Mapping out templates
These days, websites are built using templates. Whether you use a popular open-source CMS like WordPress (or Umbraco, like this website) or you have a custom built platform, the situation is the same. Several page templates will be created, to cater for different page types, which is dependent upon what content needs to go on each page.
A simple example of an ecommerce store templates:
- Homepage
- Category page
- Subcategory page
- Product page
- Checkout page
- Blog 'homepage'
- Blog category page
- Blog post
- Etc...
Once you have a list of all the page templates, you can then decide which page templates you think could/should include structured data markup, and then for each one, determine what markup you think you could include.
Importantly, this step allows you to rule out certain pages that you think are inappropriate. In the example above, for instance, the checkout page is not one that would make any sense to mark up with structured data.
Our methodology was going to take a 3-step approach:
- Every page would include some core Schema, which would be automatically populated.
- Based on page template, some pages would also include additional blocks of schema, again automatically populated.
- The author can manually add certain additional schema blocks, from a small list of additional types, using built-in generators.
Defining our core Schema
This is the base schema we want to include on every single page, regardless of template.
Examples for page templates
Following discussions of the above with our developer, the core thing he wanted for each of our page templates was a worked up example. So, for each page template, we clarified exactly what schema we wanted in addition to the core script, and what the additional code looks like on an example page.
Homepage - Schema code example Lots of websites add Organization schema to their homepage, we were in fact wondering if we should do the same. However, we also wanted to mark up a page as SoftwareApplication, given to the fact that Sitebulb is a... Software Application.
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Sitebulb",
"url": "https://sitebulb.com",
"description": "A brilliant tool for SEO audits",
"applicationCategory": "SEO",
"operatingSystem": "Windows, macOS, Linux"
}
About page - Schema code example
Per the above, we decided to make our About page the one which contained our Organization schema. There is varying advice about how Organization should be handled. Google say ' only put it on one page', whilst offering no reason why it can't go on all pages.
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Sitebulb",
"url": "https://sitebulb.com/about/",
"logo": "https://sitebulb.com/images/icons/logo.svg"
}
Author pages - Schema code example
Author pages are an interesting one, since we have recently started working with guest authors, and we have been creating an author page for them on our site.
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Patrick Hathaway",
"sameAs": "https://twitter.com/HathawayP"
}
Hints pages - Schema code example
The Hints pages on our website don't offer much in terms of structured data opportunities. They do utilize breadcrumbs, and the logic for building them is already built into the system, so we are able to add the BreadCrumbList markup, like so:
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "https://sitebulb.com/",
"name": "Home"
}
}
]
}
Guides pages - Schema code example
Our Guides pages are pages like this one, which are effectively blog posts - as such we want to use the BlogPosting markup.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "An exciting page headline",
"description": "What an interesting post we have here",
"image": "https://sitebulb.com/images/example.png",
"author": {
"@type": "Person",
"name": "Patrick Hathaway"
},
"publisher": {
"@type": "Organization",
"name": "Sitebulb"
},
"datePublished": "2021-02-12",
"dateModified": "2021-02-14"
}
Manual implementation
All of the examples above are designed to populate automatically, with different markup 'blocks' being included on different page templates. However we also wanted to optionally include FAQ schema on some pages, which is not easy to automate.
FAQ Page generator
We didn't need to reinvent the wheel with this one. There are plenty of FAQ Page generators out there, so we just asked our developer to build one like the example from Merkle:
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is Sitebulb?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Sitebulb is a tool for SEO audits."
}
}
]
}
Developer notes
I actually ended up sharing this specific document with our developer, so he understood our methodology and could see the code examples and documentation links.
To contextualise this question a little, I have seen examples of ecommerce sites whose Product markup breaks down on certain types of products, for example 'Price on Application', which ends up making the schema markup invalid.
Always be validating (part II)
As we iterated through the development process for the page templates, we would continually validate one page at a time, using [Google's SDTT or a similar alternative](/content/resources/guides/automating-structured-data-on-sitebulbcom/# "Structured Data Testing Tool Alternatives"/index.html). However, once the code was set live on the site, we needed to move to sitewide validation.
Since we'd pushed the code changes live on the website as we were tidying things up, Google Search Console also chimed in with a few parsing errors:
These came from a few marginal page templates we had forgotten about, and a couple of instances where we needed to update some data fields in the CMS, as the schema code was 'expecting' data (e.g. we did not have 'publish date' on a few older posts).
A documented framework for your developer
This post was originally inspired by a question on our structured data Q & A webinar:
To our developer, that stuff didn't matter so much. Once we'd gone through the fundamental aspects - the core schema and the node identifiers linking everything together - the most important thing for him was code examples for each of the different page templates. From there he was just following the logic and building out the scripts, something he is familiar and comfortable with already.