One of the features of Yoast SEO for Wordpress is structured data/schema. But, how do you customize this data. What if for example you would like to add a phone number or a sponsor to the Organization
schema? Or maybe you don't want to use gravatars in the Person
schema? This is what this series is about.
This first part gives an introduction on how Yoast implemented structured data. This is important because you need to understand the structure of the json-ld before you can alter it. Parts 2 to 4 will deal with actual customization.
A sidenote: this article assumes you know about structured data/schema, json-ld, yoast SEO and wordpress. But, we take our time to explain the code.
Interlinked pieces
The team at yoast implemented a modular and flexible approach to json-ld. They pulled apart all the structured data into single reusable schemas (modular) called a pieces
. These pieces are linked to each other through ID's (flexible) and get outputted as inline json.
<script type="application/ld+json" class="yoast-schema-graph">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.mycompany.com/#Organization",
"url": "https://www.mycompany.com/",
"name": "My Company"
}
]
}
</script>
The "@graph" property is an array that holds all of the different pieces. Currently it holds only one piece, an Organization
(simplified example):
- the "type" property refers to https://schema.org/Organization.
- the "id" property is an auto generated unique identifier: "site url" + "#organisation".
Let's add 2 more pieces: Website
and Webpage
:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://www.mycompany.com/#Organization",
"url": "https://www.mycompany.com/",
"name": "My Company"
},
{
"@type": "Website",
"@id": "https://www.mycompany.com/#Website",
"url": "https://www.mycompany.com/",
"name": "My Company",
"publisher": {
"@id": "https://www.mycompany.com/#Organization"
}
},
{
"@type": "Webpage",
"@id": "https://www.mycompany.com/page1/",
"url": "https://www.mycompany.com/page1/",
"name": "Page 1",
"description": "Page 1 description",
"isPartOf": {
"@id": "https://www.mycompany.com/#Website"
}
}
]
}
Both Website
and Webpage
have their own @types and IDs. Crucial to notice here are the properties that link these pieces together. Website
has a property "publisher" which refers to the id of the Organization
. Webpage
has a property "isPartOf" that refers to the Website
id.
Webpage
refers to Website
. Website
refers to Organization
. This is a clever but not obvious solution. Referring is not obvious because there is no official way of doing this. Json-ld is messy, it's not clearly documented.
A solution without referring would involve having to repeat entire schemas, nested inside other schemas.
Organization
-
Website
- publisher:
Organization
all over again
- publisher:
-
Webpage
- isPartOf:
Website
all over again - publisher:
Organization
all over again
- isPartOf:
It would be a bloated mess. Yoast solved this for us by using IDs. But, this also means that the json-ld is interconnected and you should be carefull before altering it.
The basic schemas
The second thing you need to understand about structured data in Yoast SEO is that it uses 3 basic pieces on every page, post, taxonomy, custom post type,... These 3 pieces are the ones we already used as examples:
-
Organization
(or a subtype likeCorporation
,LocalBusiness
or a subsubtype likeStore
,Restaurant
,...) Website
-
Webpage
I have to admit. When I first saw these basic schemas I thought Website
and Webpage
were unnecessary and my first instinct was to remove them. I was wrong. They don't seem very important on their own but are needed to hold everything together.
Let's take a look at a simplified Article
piece as an example:
{
"@type": "Article",
"@id": "https://www.mycompany.com/blog/hello-world/#article",
"isPartOf": {
"@id": "https://www.mycompany.com/blog/hello-world/#webpage"
},
"author": {
"@id": "https://www.mycompany.com/#/schema/person/2fa9055e7ef234fa04dd717e6aaed799"
},
"headline": "Hello world!",
"publisher": {
"@id": "https://www.mycompany.com/#Organization"
}
},
You can see that Article
has a lot of referrals. It's linked to WebPage
, Organization
and a Person
piece. But, it is not directly linked to Website
.
Yoast has thought this through for us and came up with this structure. It might seem a bit overwhelming at first but it works. Simply removing a piece would break the chain of referrals and leave us with 404 Piece not Found
situations.
Summary
When you first look into the json-ld that Yoast SEO renders onto the page it may be a bit confusing. The structured data is modular: different pieces are linked using IDs.
The second thing that may be confusing is that every page uses the same 3 basic pieces: Organization
(or a subtype), Website
and Webpage
. Accept this basic structure because it ties in with other pieces that Yoast SEO outputs and you can also use it for your own custom pieces.
Now that you understand this we can talk about customizing. Part 2 of this series covers adding, changing or removing piece properties and removing a piece. Part 3 and part 4 will show you how to add a piece.