DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Customizing Yoast SEO's structured data with schema API part 2
Peter Jacxsens
Peter Jacxsens

Posted on • Updated on

Customizing Yoast SEO's structured data with schema API part 2

In the first part of this series I explained how Yoast SEO implements structured data. Now, we will have a look some basic ways to customize the schemas.

Schema API

Yoast SEO has a build in api for altering it's schema output: Schema API. This is what we will be using.

To make development in this mode easier, yoast also provided a little snippet that turns on dev mode for structured data. This will print the json-ld un-minified, so you can easely read it. Just drop this in your functions.php. (don't use this in production)

add_filter( 'yoast_seo_development_mode', '__return_true' );
Enter fullscreen mode Exit fullscreen mode

Customize schema props

To change a property of a piece (a single schema), we use the wpseo_schema_<class> filter. The <class> refers to the schema you want to change. So, for Article you would use wpseo_schema_article.

Example 1 Add property "email" to Organization:

// functions.php

add_filter( 'wpseo_schema_organization', 'add_email_to_organization' );
function add_email_to_organization( $data ) {
  $data['email'] = get_option('company-email');
  return $data;
}
Enter fullscreen mode Exit fullscreen mode

This would result in: (simplified example)

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://www.mycompany.com/#Organization",
      "url": "https://www.mycompany.com/",
      "name": "My Company",
      "email": "info@mycompany.com"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The $data object holds all the properties: "@type", "id", ... All we have to do is add a new property and then return $data.

In case you are confused by get_option. That is not schema API but WordPress settings API. It allows you to customize WordPress settings and preferences. The get_option function is then used to retrieve the content. You can use get_option to retrieve data you're familiar with like get_option("blogname") or get_option("siteurl"). In the above example we retrieve a custom field "company-email".

Example 2 Change an existing property:

// functions.php

add_filter( 'wpseo_schema_organization', 'change_name_of_organization' );
function change_name_of_organization( $data ) {
  $data['name'] = "A custom name";
  return $data;
}
Enter fullscreen mode Exit fullscreen mode

This would result in: (simplified example)

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://www.mycompany.com/#Organization",
      "url": "https://www.mycompany.com/",
      "name": "A custom name"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

As you can see, adding or editing (overwriting) a property is pretty much the same.

Example 3 remove property "potentialAction" from Article:

// functions.php

add_filter( 'wpseo_schema_article', 'remove_potentialAction_property_from_article', 11, 1 );
function remove_potentialAction_property_from_article( $data ) {
  if (array_key_exists("potentialAction", $data)) {
      unset($data['potentialAction']);
  }
  return $data;
}
Enter fullscreen mode Exit fullscreen mode

The code seems pretty self explanatory. If the property "potentialAction" exists, remove it.

Example 4 Conditionally add "award" to Article.

It is important to note that you can use all of WordPress' conditional logic in these functions. Let's say you received an award for a certain blog post and would like to add that to your structured data.

// functions.php

add_filter('wpseo_schema_article', 'conditionally_add_award_to_article');
function conditionally_add_award_to_article( $data ){
  if ( ! is_single( 123 ) ) {
    return $data;
  }
  $data['award'] = 'Some Fancy Award';
  return $data;
}
Enter fullscreen mode Exit fullscreen mode

Remove an entire piece

To remove a piece we use the wpseo_schema_graph_pieces filter. Let's say we want to remove the Breadcrumb schema from the website.

// functions.php

add_filter( 'wpseo_schema_graph_pieces', 'remove_breadcrumbs_from_schema', 11, 2 );
/**
* Removes the breadcrumb graph pieces from the schema collector.
*
* @param array  $pieces  The current graph pieces.
* @param string $context The current context.
*
* @return array The remaining graph pieces.
*/
function remove_breadcrumbs_from_schema( $pieces, $context ) {
    return \array_filter( $pieces, function( $piece ) {
        return ! $piece instanceof \Yoast\WP\SEO\Generators\Schema\Breadcrumb;
    });
}
Enter fullscreen mode Exit fullscreen mode

As the comments say, we remove Breadcrumb from the schema collector. So the function that renders the Breadcrumb piece doesn't get called.

But, as we saw in part 1, this leaves us with a problem. All the pieces are linked. After removing Breadcrumb, Webpage is still referring Breadcrumb.

{
  "@type": "WebPage",
  "@id": "https://www.mycompany.com/page1/#webpage",
  "url": "https://www.mycompany.com/page1/",
  "name": "Page 1",
  "isPartOf": {
    "@id": "https://www.mycompany.com/#website"
  },
  "breadcrumb": {
    "@id": "https://www.mycompany.com/page1/#breadcrumb"
  }
}
Enter fullscreen mode Exit fullscreen mode

Luckily, we already know how to remove a property from a schema piece:

// functions.php

add_filter( 'wpseo_schema_webpage', 'remove_breadcrumbs_property_from_webpage', 11, 1 );
function remove_breadcrumbs_property_from_webpage( $data ) {
  if (array_key_exists('breadcrumb', $data)) {
    unset($data['breadcrumb']);
  }
  return $data;
}
Enter fullscreen mode Exit fullscreen mode

Summary

You now know how to add, change or remove properties from a single piece. We've also shown an example of removing a piece. An important note here is to look for links before you edit or remove things. Make sure not to break the chain.

On a last note I need to mention this is only an introduction. There are more filters and possibilities available. So you should really invest some time reading the schema API docs. Don't worry, they are short.

In the third and fourth parts of this series, we will look into adding custom pieces.

Top comments (0)

🌚 Life is too short to browse without dark mode