Key takeaways:
- Marking up important elements on your page with structured data is an efficient way to communicate to search engines:
- What a page is about and what the content mentions with reference to WikiData.
- How the topic relates to other pages on the website
- Why search engines should trust your content over other pages in its index
- Words on a page require significant computation and without schema, you are relying on Google to interpret your content for you whereas schema removes unnecessary ambiguity.
- Effective semantic SEO will reduce the time you wait for a page to be indexed and rank on Google search.
- Every page on your website should be set up as webPage schema.
- Use the free Schema App Paths Tool to find out how two schemas can be connected together.
What is semantic SEO?
Semantic search, semantic SEO, entity-based SEO all refer to the same practice but I’m not going to explain what semantic search engine optimisation is (or is not).
Instead, I will defer to my colleagues who have expertise in the subject matter:
- ‘What is semantic SEO’, published on WordLift
- ‘Semantic SEO: How to drive more meaningful traffic’, by Michel Fortin, published on Wix
- ‘Entity-Oriented Search’ by Krisztian Balog, available on Kindle
In a nutshell, semantic SEO is the practice of translating unstructured data into structured data. It reduces your reliance on Google to get things right by removing ambiguity. And the purpose of semantic SEO is to amplify your investment in user experience so that you can extract maximum return on your investment.
What is connected schema and what does it look like?
Most of the web’s structured data markup is incomplete, incorrect, or blatantly missing.
For example, I often come across the following issues:
- Product detail pages (PDPs) marked up as Product schema
- Non-news articles marked up as Article schema
- Homepage marked up as Organization schema
- Landing pages marked up as FAQPage schema
Often, this comes down to three things:
- Relying on a plug-in to automate structured data markup, and/or
- Misunderstanding of how to leverage entity-based SEO, and/or
- Trusting everything Google says.
Many of you, upon reading the above, have reached out to me to ask why I have stated product pages should not be marked up as product schema.
Many of you have cited to me ‘How To Add Product Structured Data’ by Google.
This is what I’m saying:
- Product detail pages (PDPs) should have Product schema
- Non-news articles should use BlogPosting or SocialMediaPosting schema
- Homepages should have Organization schema
- Landing pages should use FAQPage schema
But each of these schema types should be nested as part of WebPage schema.
In the above example, the category page from THE ICONIC has only BreadcrumbList schema (see below).
If I were THE ICONIC, I would be marking up every important element on the page because the keyword ‘adidas’ gets 2.4 million searches per year in Australia alone.
I would markup the ‘adidas originals’ product listing page with nested schema, as follows:
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@graph":[
{
"@type":"collectionPage",
"headline":"adidas Originals | Buy adidas Originals Shoes & Clothes Online Australia - THE ICONIC",
"url":"https://www.theiconic.com.au/adidas-originals/",
"@id":"https://www.theiconic.com.au/adidas-originals/#collectionpage",
"description":"Shop the latest range of adidas Originals shoes, clothing and sportswear at THE ICONIC today. Enjoy the option of free and fast delivery throughout Australia, including Sydney, Melbourne & Brisbane.",
"about":{"@id":"https://www.wikidata.org/wiki/Q4682711"},
"relatedLink":["https://www.theiconic.com.au/men-adidas-originals/","https://www.theiconic.com.au/women-adidas-originals/","https://www.theiconic.com.au/adidas-originals-kids/"],
"mentions":[
{
"@type":"product",
"name":"Adicolor Classics 3-Stripes Pants",
"brand":{"@id":"https://www.wikidata.org/wiki/Q4682711"},
"url":"https://www.theiconic.com.au/adicolor-classics-3-stripes-pants-1162427.html",
"@id":"https://www.theiconic.com.au/adicolor-classics-3-stripes-pants-1162427.html#product",
"offers":{
"@type":"AggregateOffer",
"highPrice":"110",
"lowPrice":"90",
"availability": "https://schema.org/InStock",
"priceCurrency":"AUD"
}
},
{
"@type":"product",
"name":"Adicolor Classics 3-Stripes Tee",
"brand":{"@id":"https://www.wikidata.org/wiki/Q4682711"},
"url":"https://www.theiconic.com.au/adicolor-classics-3-stripes-tee-1178757.html",
"@id":"https://www.theiconic.com.au/adicolor-classics-3-stripes-tee-1178757.html#product",
"offers":{
"@type":"offer",
"price":"27.50",
"availability": "https://schema.org/InStock",
"priceCurrency":"AUD"
}
},
{
"@type":"product",
"name":"Superstar - Unisex",
"brand":{"@id":"https://www.wikidata.org/wiki/Q4682711"},
"url":"https://www.theiconic.com.au/superstar-unisex-998179.html",
"@id":"https://www.theiconic.com.au/superstar-unisex-998179.html#product",
"offers":{
"@type":"AggregateOffer",
"highPrice":"160",
"lowPrice":"150",
"availability": "https://schema.org/InStock",
"priceCurrency":"AUD"
}
}
],
"isPartOf":{
"@type":"website",
"name":"THE ICONIC",
"url":"https://www.theiconic.com.au/",
"@id":"https://www.theiconic.com.au/#website",
"publisher":{
"@type":"organization",
"name":"THE ICONIC",
"hasMerchantReturnPolicy":"https://theiconicsupport.zendesk.com/hc/en-us/sections/4416116807065",
"parentOrganization":{
"@type":"organization",
"name":"Global Fashion Group",
"url":"https://global-fashion-group.com/",
"@id":"https://global-fashion-group.com/#organization"
}
}
}
}
]
}
</script>
💡 Copy and paste the above code snippet and paste it into Schema.org’s validator.
Similarly, the following screenshot from classyschema.org shows the knowledge graph that was created by the same nested JSON-LD.
On the other end of the spectrum, the following screenshot shows a webpage having 34 individual schema types described with structured data markup.
The problem in the above example is that all 34 schema types are disconnected from one another.
That is, the schema markup is telling search engines that the URL is all these 34 things – which is incorrect.
Instead, the correct way to describe the URL is the following:
- This is a webpage with the following URL, headline, and URI.
- It has a number of answers to frequently asked questions where the information has been verified by a person who also happens to be the owner of the company.
- There are a number of images and videos embedded on the page.
- The webpage was published on this date and was recently updated on this date.
- This URL is part of a website with this name, accessed at this URL, with this URI.
- The website is published by an organisation with this name, founded by a person and this is their LinkedIn profile URL as proof.
The above tells how each individual schema type relates with each other and this helps the search understand what it is rendering from the HTML.
To describe the same story using connected schema with JSON-LD would look like this:
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@graph":[
{
"@type":"WebPage",
"headline":"Certified Authentic Pre-Owned & Used Rolex Watches | Bob's Watches",
"url":"https://www.bobswatches.com/rolex/",
"@id":"https://www.bobswatches.com/rolex/#webpage",
"inLanguage":"en-US",
"about":{
"@type":"thing",
"name":"rolex",
"@id":"https://www.wikidata.org/wiki/Q62288"
},
"significantLink":[
"https://www.bobswatches.com/rolex-submariner-1.html",
"https://www.bobswatches.com/rolex-datejust-1.html",
"https://www.bobswatches.com/rolex-daytona-1.html",
"https://www.bobswatches.com/rolex-day-date-1.html",
"https://www.bobswatches.com/rolex-president-1.html",
"https://www.bobswatches.com/rolex-gmt-master-1.html",
"https://www.bobswatches.com/rolex-explorer-1.html",
"https://www.bobswatches.com/rolex-yacht-master-1.html"
],
"mentions":[
{
"@type":"thing",
"name":"Rolex Submariner",
"@id":"https://www.wikidata.org/wiki/Q3440353",
"url":"https://www.bobswatches.com/rolex-submariner-1.html"}
],
"isPartOf":{
"@type":"website",
"name":"Bob's Watches",
"@id":"https://www.bobswatches.com/#website"
}
},
{
"@type": "FAQPage",
"isPartOf":{"@id":"https://www.bobswatches.com/rolex/#webpage"},
"reviewedBy":{
"@type":"person",
"name":"Paul Altieri",
"sameAs":"https://www.linkedin.com/in/paul-altieri-43732621/",
"knowsAbout":{"@id":"https://www.wikidata.org/wiki/Q62288"},
"owns":{"@id":"https://www.bobswatches.com/#organization"}
},
"mainEntity": [{
"@type": "Question",
"name": "How Much Is The Cheapest Rolex?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The Oyster Perpetual Reference 276200 for women is the least expensive option, with an MSRP of $5,500. The Oyster Perpetual Reference 126000 for men is the next lowest priced option, with an MSRP of $6,100."
}
},{
"@type": "Question",
"name": "Why Do Rolex Cost So Much?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Rolex utilizes 904L stainless steel in all of its collections to ensure the durability and longevity of its timepieces. This high-quality steel is a major contributor to the premium price of Rolex watches. The Rolex Datejust is an example of a watch that incorporates 904L stainless steel."
}
},{
"@type": "Question",
"name": "Is Rolex A Good Investment?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Is it a good idea to invest in a Rolex watch? In general, Rolex watches tend to retain their value better than other luxury brands."
}
},{
"@type": "Question",
"name": "How Much Does A Real Rolex Cost?",
"acceptedAnswer": {
"@type": "Answer",
"text": "The price of a new Rolex watch typically ranges from $7,000 to $12,000. Pre-owned models are sometimes less expensive, with prices ranging from around $4,000 to $6,000. Some rare models may be more expensive, even when pre-owned."
}
}]
},
{
"@type": "VideoObject",
"name": "Rolex History",
"description": "Since 1905, Rolex has been at the forefront of mechanical watchmaking and has become one of the most well-known and respected luxury brands in the entire world. Synonymous with precision, quality, and exclusivity, Rolex watches are instantly recognizable for their iconic designs, making them an internationally recognized symbol of success and personal accomplishment.
From highly-capable sport and professional watches, such as the Submariner, Daytona, and GMT-Master, to elegant and classically styled timepieces like the Datejust, Oyster Perpetual, and Day-Date President, Rolex manufacturers watches that perfectly cater to nearly every possible lifestyle.",
"thumbnailUrl": "https://www.bobswatches.com/images/managed/rolex-watches-video-1.jpg",
"uploadDate": "2019-01-10",
"duration": "PT0M59S",
"publisher": {
"@type": "Organization",
"name": "Bob's Watches",
"logo": {
"@type": "ImageObject",
"url": "http://www.bobswatches.com/image/bobs-watches-logo1.gif",
"width": 120,
"height": 30
}
},
"contentUrl": "https://www.youtube.com/watch?v=Wv-ZY9eWE3Q",
"embedUrl": "https://www.youtube.com/embed/Wv-ZY9eWE3Q",
"isPartOf":{"@id":"https://www.bobswatches.com/rolex/#webpage"}
}
]
}
</script>
💡 Copy and paste the above code snippet and paste it into Schema.org’s validator.
Why should schema be connected to each other?
The goal of structured data markup and nested schema is to create your very own knowledge graph and this is what a knowledge graph created with JSON-LD can look like.
💡 In fact, the visualisation is from the JSON-LD I wrote for THE ICONIC ‘adidas originals’ PLP.
There are 2 distinct benefits of connected schema
The first advantage of connected schema is that you can describe a schema type once and then call upon it using its unique identifier.
For example, my about page is where my Person schema sits.
My Person schema has the following properties:
- my name
- image (i.e., my profile photo)
- what I know, linked to a WikiData entry re: SEO
- where I graduated
- my current job title, and
- where I work.
My Person schema has been converted into an URI with the @id – https://danielkcheung.com.au/about/#person. And this is the secret sauce behind connected schema.
With this, I can tell Google I am the author of any webpage on my website by referencing my Person schema’s URI.
For example:
author:{"@id":https://danielkcheung.com.au/about/#person"}
Similarly, I can tell search engines that I am the creator and copyrighter holder of an image.
For example:
creator:{"@id":https://danielkcheung.com.au/about/#person"},
copyrightHolder:{"@id":https://danielkcheung.com.au/about/#person"}
More importantly, for my about page, I can use JSON-LD to communicate the main focus of the page is my person schema by referencing the URI of my person schema.
For example:
about:{"@id":https://danielkcheung.com.au/about/#person"}
The second benefit of connect schema is the ability to connect structured data markup that is dynamically generated (e.g., product schema, breadcrumbs) with manually created schema (e.g., webpage, FAQPage, itemList).
For example, at my last in-house role, I asked the developers to create an @id for every product detail page (PDP) and to append #product to create the URI.
This was scaled across 40+ PDPs.
Then I custom wrote JSON-LD describing FAQs on the page, nested it as part of the webpage, and made the main entity of the page being the product by referencing the URI.
This part was not scalable.
But the end result allowed bespoke schema properties tied to the product on the webpage.
For example:
This type of implementation is ideal when developer resources are scarce.
Every webpage should be setup as WebPage schema with other schema types connected to it
If you take away anything from this article it is this.
That is, every page on your website should be defined as webPage schema even if it is a product page or a blog post.
Read the above again until it clicks because it is a pillar of semantic SEO.
The advantage of using webpage schema is that you can describe the following attributes:
- What the page is about using the mainEntity or about item property
- Who the author(s) of the content is using author item property
- What experience makes the author a qualified subject matter expert by using:
- knowsAbout item property and referencing WikiData
- jobTitle item property
- alumniOf item property
- honorificPrefix and honorificSuffix item properties (e.g., Dr, PhD)
- affiliation item property
- hasOccupation item property
- knowsLanguage item property
- What multimedia exists on the page that is directly relevant to the primary topic of the page using image or video item properties
- Topics, things, or entities the page references using the mentions item property
- Relevant internal webpages using significantLink or relatedLink item properties
- Who the intended audience of the content is using the audience item property.
If you grab this URL of this page and put it into Classy Schema, you will see how I’ve applied this.
To see the full list of attributes you can use to describe a webpage, see the Schema.org documentation.
Common scenarios of nested schemas
Connected schema is useful when you want to communicate the following:
- The relationship between image(s) and the webpage that they’re embedded on.
- The relationship between the webpage and the website.
- The relationship between the website and the entity behind it.
- Who the authors and/or contributors of the content are.
- Who the editors and/or reviewers of the content are.
- What makes the author, editors contributors, or reviewers qualified for their roles.
- The relationship between specific sections of a webpage to the main focus of the page.
- The relationship between products and the category page they’re displayed on.
As more content on the web is generated with large language models (LLMs) such as ChatGPT, Google will place more weight on verifying who the authors, contributors, and editors are of the content and one of the most effective ways to do this is through Person schema markup.
How to connect different schema types together
The practice of connected schema is also known as nested schema.
It involves telling search engines how one schema type relates to another.
The way to do this is to turn each schema type into a URI then use an appropriate connector.
💡 I won’t explain what a URI is and how it is different to a URL in this article but I do recommend you read ‘The Real Difference Between a URL and a URI’ by Daniel Miessler.
To turn a schema type into a URI, you have to add a hashtag to the end of the URL, followed by a string of text.
For example:
https://danielkcheung.com.au/how-to-implement-semantic-seo/#blogposting
The string of text can be anything – but I recommend that you use something that is easy to remember and a pattern that you can replicate across same schema types.
The same URL can have spawn as many URIs as required.
For example:
https://danielkcheung.com.au/how-to-implement-semantic-seo/#blogposting
https://danielkcheung.com.au/how-to-implement-semantic-seo/#webpage
https://danielkcheung.com.au/how-to-implement-semantic-seo/#faq
https://danielkcheung.com.au/how-to-implement-semantic-seo/#image01
https://danielkcheung.com.au/how-to-implement-semantic-seo/#image08
Once you have a URI, you can nest it with another schema on the same page or different webpage.
💡 One of the FAQs in this article answers the question of how you can know if one schema type can be connected to another. It involves using the free Schema App Paths Tools, selecting the first schema type from a drop-down, then selecting the second schema type from a drop-down. The tool will then spit out all possible ways the two schemas can be related to each other.
Common connectors I use to nest schema:
- isPartOf
- mainEntity or mainEntityOfPage
- hasMap
- author
- creator
- editor
- reviewedBy
- publisher
- parentOrganization
- about
- mentions
Frequently Asked Questions
Recommended reading
- Watch me apply semantic SEO using Person schema
- Should a homepage have schema markup? And if so, what?
- How to use Organization schema
- Subscribe to my YouTube channel Scheming Schemas to see behind-the-scenes execution of semantic SEO
- 11 advanced schema types you should start using today
- How to demonstrate EEAT with connected schema