How To Improve WordPress SEO with Schema.org

Schema.org provides you a good way to optimize your website for search engines. SEO surely means much more than that, but the usage of Schema.org will improve your visibility to Google & Co. a lot. Have you ever, for example, checked out movie search results at a website like IMDB.com or Wikipedia.org? They will mostly show you additional information for that particular movie, such as a trailer link, a link to release dates, maybe user ratings for this movie (check out the tiny yellow stars there!) and sometimes information about the actors, the director and much more, depending on your search query – and the website’s markup with Schema.org. So Google is not that intelligent that they know what the website is about – you gotta ensure this yourself by adding Schema.org microdata. While it does not directly improve your website’s rankings, the search results for your page will certainly look more appealing to users since additional information will be included.

What is Schema.org microdata?

Schema.org is a set of structured microdata markup. It allows you to add specific attributes to the HTML tags in your website to tell search engines and even other web services about your content. When you browse around their website, you will find something like a huge ordered list which shows you all the different kinds of contents you can present using their microdata markup. Schema.org is the recommended standard for working with microdata (it is supported by Google, Yahoo, Microsoft and more!), and it is the successor to Data-Vocabulary.org which you will still see pretty often on websites – although you should use Schema.org as of today.

How To Generally Use Schema.org

There are two different kinds of things when working with microdata. You have some types of content, and all the types have a whole bunch of properties. So when you want to show the search engines that the information inside a <div> container is about a specific book, it has to look like this:

So as you can see, the information about this type ends when closing the <div> again, remember that.

Now we get to the properties, this is even more simple. If you want to make sure that Google gets to know the books name and the author, add the following markup inside your <div> you previously created.

See how easy it works? Let me remind you though: we can only use the properties “name” and “author” because they are registered properties of the type “Book” as specified by Schema.org. We could not use a property like “actors” here (which wouldn’t make sense anyway) since this one is registered for types like “Movie” or “TVSeries”, so Google would not understand that. So always make sure you know the type you want to use and which properties it supports – luckily, you have Schema.org which provides you all of this information.

And there’s another thing which is really valuable: You can nest Schema.org markup, like you nest the HTML tags. Let me explain that: Some properties of a given type require not only a simple text, but another microdata type. For example, the property “bookFormat” (to stick with our example) requires a type called “BookFormatType” which can be an instance like either “Ebook”, “Hardcover” or “Paperback”. So this would be added inside our <div> like so:

Okay, there are even better examples since “BookFormatType” is a pretty simple type. You could add the “publisher” of the book. This requires a type called “Organization” which itself has its own properties like “name”, “email”, “logo” or “address” and more. Everytime you specify such a type that has its own properties, make sure to use the itemscope attribute in addition to the itemtype attribute. So here’s what the markup of all this stuff will look like:

As you can see, there’s even an additional type “PostalAddress” which contains the different elements of an address, so not only is the “Organization” nested inside the “Book”, the “PostalAddress” is also nested inside the “Organization”. Also take care of the meta tag used in there – you are allowed to include such information which is invisible to the visitor of the website as long as you do not overuse it. And the last thing (which is really important) you should know is that all the different types are set up in a tree structure by Schema.org (check out this page as a reference), so any child type inherits the properties of its parent type. Some types also have several different versions which might be more precise, for example you could also have used “Corporation” instead of “Organization” in the example above.

How To Test Your Markup

You can easily test your Schema.org markup. All you have to do is enter the URL of your page in the Google Structured Data Testing Tool. It will then show you all the information it can fetch from your page, and you will also see a preview of what a search result could look like. It currently does not fully support the looks of Schema.org markup for the search result preview, so please check the bottom of the website where it presents the data it received through your markup.

How To Use Schema.org in WordPress

To use Schema.org in WordPress is as easy as described above. There are more than a million ways to do it, so I encourage you to find your own way. Here in this article, I can only show you an example.
For this example (and generally) you should have the amazing plugin WordPress SEO installed and activated. I will show you how to set up your website so that it contains the most important elements of the “WebPage” type and some information about the business behind it. You have to edit your theme or create a child theme.

Setting Up WebPage Information

The <html> tag of your website should contain the type of your website. So in addition to the language_attributes function, include another function called yourtheme_html_schema within your first tag.

You can insert the new function in your theme’s functions.php file. It should look like this:

Having this function set up, you now have a first Schema.org microdata markup that tells Google what kind of WebPage is displayed. WebPage is the default, and it is only used when none of the criteria above match. Keep in mind that you should add custom post types that handle specific items to the array as specified in the comment above.

Adding Schema.org markup to the header

Now we’re gonna start modifying the <head> the website. To add the property “name”, modify your header.php by simply adding the attribute to the title.

Now you should add another function that creates Schema.org markup from the canonical and description meta tags in the <head>. For this, we will use the global class WPSEO_Frontend from the WordPress SEO plugin.

UPDATE: As of WordPress SEO version 1.7.2, the above code does not work any longer. Please use the code right below instead.

Adding breadcrumbs to your page

Some short words about breadcrumbs: The WordPress SEO plugin provides a great way to embed breadcrumbs. All you need is to add the following code to your theme where you want the breadcrumbs to show up.

However, these breadcrumbs are realized using the old Data-Vocabulary markup (as explained in the first paragraph of this article) which is fine though: for an unknown reason, the Schema.org markup for breadcrumbs is not really giving Google the information it should receive. So, keep in mind to check for updates on this regularly, but for now I recommend you to still use the old markup which the WordPress SEO plugin provides.

Marking the main content of your page

Now you need to edit your main content container div that should have an id like “content” or something similar. Modify it in every theme file (single.php, page.php, archive.php and all the others…) to let Google and the other search engines know where your main content is located:

You should now markup your content. Please don’t be mad that I didn’t include a whole tutorial on this, but as I said, there are more than a million ways of handling this. If you have some content which already has Schema.org types that perfectly match it (for example when your page is about movies, books or software applications), you will find out that this is fairly easy. I advise you to spy at some HTML code of other websites that use Schema.org markup, for example ebay.com, IMDB.com or ticketmaster.com.

Inserting business information with Schema.org

As a final task of this simple tutorial, I’ll show you how to insert business information for your WordPress website with Schema.org. In this example, this will be a an “Organization” of the more specific type “LocalBusiness”. I recommend you to create a simple text/html widget somewhere at the bottom of your page which will also work as a kind of contact widget for your visitors. Make sure it is outside your “WebPageElement” you created above, since it should be a direct child of the “WebPage” type for best results. The widget’s content could look like this:

This way Google would know all the above information about the business behind this webpage. And since you’re using a widget, it would also provide most of this information for the users aswell. Of course you could also combine this Schema.org markup with the techniques I showed you in “How To Add Contact Information In WordPress”. Now you’re ready to get started with Schema.org and WordPress. Optimize your website, provide your information not only to the users, but to the search engines as well!

29 thoughts on “How To Improve WordPress SEO with Schema.org

  1. Thanks so much for this article which I stumbled upon last night. I am starting to get my head round schema and how to use it in WordPress.

    I had a few questions-

    1) How about microformats? Should we not bother with them anymore?
    2) I like the idea of marking up the html tag with your function. I wonder why the Yoast SEO plugin doesn’t have this baked in? I think it would be much better to have a dropdown option in the edit post/page menu in WordPress so that you can choose what type of page it is. Having said all of this- will this make a big difference in SEO?
    3) Similar to question 2, but I wonder why the Yoast SEO plugin doesn’t have much in the way of Rich Snippet options. Is it because Yoast himself doesn’t think it is important?

    Thanks again!

    1. Hi Ian,

      thanks for your response!

      Now to your questions:

      1) About microformats, I would say Schema.org markup will replace this completely sooner or later. I do not work with the old microformats any longer (except for breadcrumbs because Schema does not really do its job there) since all the information microformats can contain, Schema can contain aswell. However I guess they won’t do anything bad if you mix them up with Schema.
      2) I don’t know personally about Yoast’s opinions on that, but it is a very good point to include this for every post/page. However, using Schema.org for a whole page is going deep into WordPress themes, so maybe Yoast does not want to blow up his plugin by this. I generally think that all the Schema markup should be handled by a theme because this is the best way to make it coherent. I’m currently working on a WordPress theme framework which includes full Schema markup and which gives you the ability to do just that what you asked for – it still might take some time though.
      3) Again, I can only guess about what Yoast thinks. In my opinion Schema.org will not directly increase your search engine rankings, but it will tell Google (and others) in a precise manner what your sites are about, so like you say it is important for rich snippets (and it will become even more important since many of the ‘schemas’ are not yet implemented into rich snippets). Like in my second answer, I suppose including Schema in the plugin would simply be too big. Or maybe he is waiting for it to become more popular – which it surely will!

      I hope I could help a bit, feel free to ask if you’d like to know more!

      1. Thanks so much- really helpful. I actually brought this up with Joost de Valk on the WordPress SEO repo on GitHub. You should get involved with the conversation because it’s really interesting. I linked to your article too.

        Interestingly I get the impression that he (and others) share your view that schema should manly be handled by the theme. Certainly that makes sense with the html and title, but I did mention that it would be good to implement your code for the description and canonical tag.

        I’d be really interested in seeing some example code. What is your framework going to do? Is it basically your theme? I custom build my themes using Roots (which is a really awesome starter theme that uses HTML5 boilerplate and Twitter Bootstrap). I’d like to add microdata to the theme there.

        Someone in the GitHub thread mentioned a plugin for the Genesis framework which can add microdata to your WordPress pages/posts very easily. It looks good, but I don’t use the Genesis framework.

        I like your idea of adding widgets with schema info. It seems that WordPress doesn’t like you adding microformats to posts because it strips out the attributes. There seem to be various plugins that help here, but not sure where to start. Have you got any recommendations?

        Yoast mentioned too that Google prefers RDFa for breadcrumbs. I find that odd because Google have stated that they prefer microdata over RDFa, so why the exception with breadcrumbs? Have they stated this in public?

        Finally, do you have any views on Dublin Core? I’ve seen it used on some websites. Is it worth bothering about or is that just going overboards?

        Sorry for the long reply!

        PS I’ll link to the GitHub thread in the next reply since Disqus tend to flag links as spam.

      2. I agree with Ian. I guess we’re spoiled by the elegance of Yoast and in my investigations so far (several hours), I’ve failed to find a simple way to implement Schema Markup on a WordPress site without needing to know how to code.

        I also agree that agree that it makes sense to use markup in the theme. However, there are some pages or posts which need specific markup areas – events, or services for specific locations, for example.

  2. Great post, Felix. I thoroughly enjoyed it, and I will apply same to my client’s website, tonight. I will come back with more comments, after I’ve done so.
    Schema.org is a brilliant way to tell Google and searchers, what our website is about.
    Thanks for the detailed implementation guide.

    1. Surely there are some plugins that deal with Schema.org, but it’s hard to come up with a full easily-manageable solution since Schema is such a multifaceted thing.

      A popular thing on wordpress.org is this one: http://wordpress.org/plugins/all-in-one-schemaorg-rich-snippets/ This one’s indeed any easily-manageable solution, however this leads to limitations, for example that you cannot choose anything you like.
      About Yoast, I have no idea if he’s planning such thing.

      I personally prefer a Schema.org implementation inside a theme, or even better, a theme framework (like Genesis). Schema markup should is mostly involved with general content and post content, and that’s what themes stand for.
      I have actually been busy developing a theme framework myself (first version will be released soon), of course it will feature much more than just Schema.org, but this will also be an important piece of it.

      1. I personally use the Genesis framework with the Dynamic Website Builder (best tool out there for wordpress theming). They do have some Schema built in, however I don’t think they have rating mark up or local SEO mark up.

        However Yoast has a Local Schema SEO plug-in he is selling for $60 something. Most likely he will add it to his SEO plug-in as it becomes more common and people are not will to pay for it. I’m sure someone will write an all in one schema theme, maybe it will be you.

    1. To wrap it up, currently there is no WordPress plugin that is a full comprehensive solution for Schema – and I doubt that there ever will be. What you mark up and how you mark it up really depends on the content of your site.

      So yeah, marking things manually should be better as long as you stick to Schema. However, a plugin might be used to make markup easier.

      Of course there are a few things in a site which occur very often, for example business information (like in the article). For these, a plugin will definitely be helpful. But concerning the posts, plugins will only help a little (e.g. mark it as a blog post and mark metadata, but not mark any of the actual contents).

  3. do you have a blog article about wordpress genesis framework when wp oembeds are active in the content? I’d like to research how to extend the function from WP codex and wrap the oembed within a schema scope. Example => A youtube video link wrapped in video schema in genesis framework.

    1. I don’t have a blog article about this topic since I never used the Genesis Framework a lot, however wrapping an oEmbed video should be pretty easy. You can either use the WordPress filter ’embed_oembed_html’ (https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-embed.php#L228) or ‘oembed_result’ (https://github.com/WordPress/WordPress/blob/master/wp-includes/class-oembed.php#L126) where I would recommend the latter since it is more specific. You should take a look at the functions get_html( $url, $args ) and data2html( $data, $url ) which are both part of the WP_oEmbed class.

  4. Really helpful article. There’s still a lot of grey areas of information regards using microdata in WordPress and your article helped a lot. What about widgets? Do you know if there’s any advantage using microdata in this case?

  5. This article helped me a lot with implementing schema.org on my website. Thanks for taking the time to write it. I have one question though regarding it’s use with wordpress SEO from Yoast.

    After the most recent update (1.7.3), your fix to add schema.org markup to the header stops working and breaks my site. It has something to do with the following line:

    $canonical = $wpseo_front->canonical( false );

    Can you advice on how to change this line to keep it’s functionality? Unfortunately, I still lack the proper coding experience.

    Thank you!

  6. Thanks so much for this! Can’t believe you don’t have more comments. I’m wondering where elseif( is_singular( array( ‘book’, ‘movie’ ) /* add custom post types that describe a single item to this array */ ) ) gets used?

  7. Hi Felix,

    your post is perfect!
    …but!

    I try to click “How To Add Contact Information In WordPress”, but teh link is broken… 🙁

    Where I can find the “How To Add Contact Information In WordPress” post?

    Thank you!

  8. Thank you for sharing. In the new function (function yourtheme) that you shared, how would you write an elseif for blog posts? The goal is to use BlogPosting (or is it Blog) as an itemtype for single post.

    1. I figured it out:

      // Is single post
      if(is_single()) {
      $type = “Article”;
      }

      I ended up using Article. You can try Blog, etc… Also, I made this the first criteria. The old first criteria in the authors example became an elseif( is_page…..

  9. What is the purpose of:
    add_action( ‘wp_head’, ‘yourtheme_meta_schema’ );

    It made duplicates of the headline and description when I used the
    Structured Data Testing Too.

    I took that line out and it seems to work ok and with out the duplicates.

  10. That is weird because the plugin uses get_transient to display the widget which validate’s the “freshness” of the data and if it has expired the data (the transient) gets deleted and that means that the DB clean up is done for you. (look at the function definition). So the only reasons I can think of for you not finding the location of the transients in the DB are:

    You have external object cache enabled, which means that the transients are not stored in the database
    You are simply not looking for the transients correctly, ex: if you have a transient named my_key then in the DB its stored with a _transient_ prefix so you get _transient_my_key and that is stored in the options table of the DB.
    If you do know what to look for and still can’t find it I’ll be happy to help you investigate.

Leave a Reply

Your email address will not be published. Required fields are marked *