How to add schema to WordPress without plugin

From time to time I get asked if it’s possible to add schema to WordPress without plugin. And the answer is yes. Even though it’s super inconvenient if you want to add Structured Data to many posts at once. But read on to learn more about schema, Structured Data and the benefits in SEO.

What is Schema?

When we’re talking about “Schema”, we normally mean Structured Data that we get from the vocabulary over at schema.org.

Schema.org offers more than 800 different “Things” that we can use to mark up our web pages. But not every “Thing” is applicable. That’s why often only a fraction of them is used.

The markup is used by search engines to learn more about your website and your singular posts in WordPress. With that code they can understand the overall context and structure of your site.

Honestly not everyone can code. But schema.org is, unfortunately, mostly code. There are different encodings but all of them are code in the end. Nevertheless, in this blogpost I want to show how to build this code and then integrate it into your own website so that you get all these nice-looking search results, that are often referred as “Rich Snippets” or “Rich Search Results”.

The different formats

As I wrote above, there are different formats: Microdata, RFDa and JSON+LD. I’m only going to show you the JSON+LD format because it’s the simplest format that can also be read easily by humans and it’s the recommended format that Google wants to see.

All the other formats (RDFa and Microdata) need to be included into the HTML code of a post which adds a lot more complexity, especially if you’re not familiar with coding at all. And, of course, this post is written to show you how you can add schema to your WordPress without using a plugin. That means that you need to code.

But don’t worry! There is ray of hope, I provide you with a simple to use Structured Data Generator (that is also built-in into my Structured Data Plugin for WordPress). That generator is free to use so that you can start right away. And therefore you overcome the hassle of coding yourself. Wohoo! 🥳

Easy schema example (without using a plugin)

Let’s take a look at the Product examples on schema.org. If you have read my post about How to add Structured Data Markup to your WordPress site, you maybe know this code already. I’ve shortened everything else out to show you what’s all about:

<script type="application/ld+json">
{
   "@context": "http://schema.org",
   "@type": "Product",
}
</script>

What search engines see

If this code snippet is integrated on a WordPress post that shows a product, the search engines can then understand that (you guessed it) they are currently viewing a product (that is for sale). Search engines usually assume that the current post is an article.

It’s true that search engines nowadays have other methods to find out if the page at question is a product page. But that requires computing power. And with more than nearly a trillion websites, search engines are happy to save any computing time, no matter how small. The solution? The webmaster of the website must incorporate structured data himself. Whether with or without a plugin doesn’t really matter.

What is the benefit of adding schema to your posts?

Let’s keep this answer short: it’s simply that you can super awesome, eye-catching search results. And when you run your WordPress site for a living, you need to beat the competition and adding schema to your WordPress site is a simple and easy thing to do to get more traction and a higher click-through-rate on search engines.

Here is an example of a product search on Google. Sony uses the product schema to get a search result like this:

Mobile Phone with search results of a Sony headset.
You can clearly see the benefit: an image, star rating and often a price as well as the availability.

You can clearly see the rating and a super nice eye-catching image. Of course, Amazon is using it as well. But just think about products that are not as popular as Sony headphones. All your competitors are maybe not using schema on their WordPress sites, but you do! Which search result do you think will be clicked then? Exactly! It’s yours! Boom!

How to add schema to WordPress without a plugin

After this little excursion we can jump right in. Let’s add tome schema code to your WordPress pages. Let’s assume that we want to feature a product on one of our posts.

I also assume that you’re using the new Block-Editor (called “Gutenberg”) in WordPress. It’s super easy to add custom code there because it has a block exactly for that. However, other page builders (like Divi or Elementor) also have Code-Blocks that you can use.

  1. Log-in to your WordPress dashboard.
  2. Edit the page you want to add schema to.
  3. Add a code block anywhere in your post (it doesn’t matter if it’s on top or at the end).
  4. Copy and paste the below code:
<script type="application/ld+json">
{
   "@context": "http://schema.org",
   "@type": "Product",
}
</script>

The following animated GIF shows everything to you step-by-step:

Step-by-Step GIF for how to add Schema to WordPress without plugin but with using the HTML block of the Block-Editor.

Good job! All done!

But wait! Isn’t there anything missing? Yes, it is! It’s not enough for Google (and most other search engines) to just tell them that the page is a product-page. In most cases they want to learn more about the product. For example the name, the price and the rating of your users. Only with that data, search engines can show a so called Rich Snippet (an eye-catching search result) for your post.

Enhance the schema with properties

Let’s edit our manually added schema even further. For this, we take a look at Googles Structured Data Reference for a product. Especially the part where it says “Required properties” is important for us. Because without these required properties, the code will produce an error in the Structured Data Test Tool that we’ll have a look later in this post.

At the time of writing this post, the following schema properties were marked as required:

  • name
  • Either review or aggregateRating or offers

Let’s add this to our code above. The name is pretty easy:

<script type="application/ld+json">
{
   "@context": "http://schema.org",
   "@type": "Product",
   "name": "Super awesome product"
}
</script>

In the next step I’ll add the offers property because we do not have any ratings to collect from our customers and I also don’t want to add a review myself. If you want to learn more about the aggregateRating property, please refer to my blog post that was written exactly for this purpose: How to properly add a rating to a Thing.

Now let’s add the offer property:

<script type="application/ld+json">
{
   "@context": "http://schema.org",
   "@type": "Product",
   "name": "Super awesome product",
   "offers": {
      "@context": "http://schema.org",
      "@type": "Offer",
   }
}
</script>

As you can see, it gets a little more complex now. This is because according to the the Product vocabulary on schema.org, the offer property expects to be a sub-schema of either Demand or Offer. I’ve decided to user Offer.

Did I lost you in this step? Structured data can be quite complicated. You would hardly believe it! That’s probably why most people prefer to use a WordPress plugin, like SNIP (my Structured Data Plugin for WordPress) for this. The creation of structured data is often much easier. Anyway. Because the main topic of this blog post is still “How to add schema to WordPress without plugin” I’ll stick to that. But I’ll use a little helper.

The Structured Data Generator

The Structured Data Generator that I’ve developed exclusively for SNIP, my WordPress Plugin, is available on my website as well. And the good thing is: it’s totally free of charge to get you going if you want to manually add a schema to WordPress.

You’ll see in a moment why there’s a huge advantage to using the generator. The following GIF shows the next steps:

The Structured Data Generator in action: building
  1. Open up the Structured Data Generator.
  2. Click the “Product” button.
  3. The generator will load all required and recommended properties as listed on Googles reference.
  4. Delete all other properties except the name and the offers attribute (to not over-complicate things later).
  5. Edit the name property and add the title of your product.
  6. Edit the offers property and select “Offer” as the sub-schema.

In this step you have three main advantages by using the Generator:

  • You don’t need to code anything.
  • The Generator loads all properties that are currently needed by Google (and maybe other search engines).
  • And it only offers the sub-schemas that can actually be added to a property. So you can’t go wrong here because the Generator takes care of it.

No we need to fill the property-fields for the sub-schema: the Offer. As you can see on the reference docs, the Offer-sub-schema has only one required property. And that is the price field. We can remove all the other properties (for now) and fill the price.

When you now click the “Generate” button, you’ll get the following code from the Structured Data Generator:

<script type="application/ld+json">
{
     "name": "Super awesome product",
     "@context": "http://schema.org",
     "@type": "Product",
     "offers": {
         "@context": "http://schema.org",
         "@type": "Offer",
         "price": "19.99"
     }
 }
</script>

A quick side note: The order of the properties is irrelevant in JSON+LD.

All done. You can update your code as mentioned above.

Test your code

After you have included the code in the Block-Editor, don’t forget to save your post. If you have a cache-plugin: flush the cache of the current post. After that, head over to either

In both tools you can either enter the URL to a post or the code that you’ve generated. I would recommend to enter the URL so that you can see the overall picture.

The Rich Results Test Tool shows "Page is eligible for rich results".
Good job! The page is eligible for rich results, says the tool!

After testing the page (I’ve used the Rich Results Test Tool) it says, that the page is eligible for rich results. Everything is green which is good. That is because we have integrated all required properties from Googles reference.

The warnings in the test tool

However, we can also see some (yellow) warnings. A click on it says things like:

  • Missing field “review” (optional)
  • Missing field “image” (optional)
  • Missing field “description” (optional)
  • etc.

As you can clearly see, the warning shows the optional (recommended) properties. There is nothing wrong if you don’t add these properties. However (as the reference says) the properties are recommended and you should add them if you can. Read more about this in my blog post about errors and warnings in Googles Structured Data Test Tool.

The errors in the test tool

If you get a red error message that says “Not all markup is eligible for Rich Results,” you need to change something to turn it green.

When you have tested your entire page, try extracting the code in question and test it again. It’s also possible that other plugins or your WordPress theme are generating structured data that has errors.

Click here if you want to learn how you can find the plugins that are causing structured data issues.

Enjoy the new results

Hopefully I could show how you can schema to WordPress without plugin.

I understand that the whole issue is very technical. And that is also the reason why schemas and generally Structured Data, are considered technical SEO efforts. However, if you have dealt with the subject a few times, it becomes easier and easier each time.

If the above is “too much” for you, take a look at SNIP (my Structured Data Plugin for WordPress). There is a free version available that you can also download directly from WordPress.org.

How to add more schema to WordPress without plugin

And here they are, more schema examples for you that you can use out of the box. Just replace the values of the properties to fit your needs. And – of course – if you want to automate things, check out my plugin!

Recipe

Google and other search engines constantly change things, so it might be that your recipe snippet looks different than the one that you can see in the image. Anyway, you’ll benefit from a nice picture, a rating and often the cooking time and the number of calories.

Here is an example code:

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Recipe",
  "cookTime": "PT0M",
  "prepTime": "PT30M",
  "description": "Donuts, a good recipe with picture from the category Cakes.",
  "image": "https://meine-website.de/donuts.jpg",
  "recipeIngredient": [
    "750,00 g flour ",
    "2,00 Packet dry yeast ",
    "50,00 ml water, lukewarm"
  ],
  "name": "Donuts",
  "author": {
    "@type": "Person",
    "name": "The WP-Buddy"
  },
  "recipeInstructions": "Mix dry yeast in a little lukewarm water and 1 tsp. sugar,
  "recipeYield": "1",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "3.33",
    "reviewCount": "10",
    "worstRating": 0,
    "bestRating": 5
  }
}
</script>

The “breadcrumbs” show the individual hierarchy levels of a website instead of just the URL itself. In addition, the individual navigation points are directly clickable from the search hit.

Breadcrumbs in Google search results.

Here is an example code that you can also use to directly import into into my schema plugin.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Electrical goods",
      "item": "https://www.idealo.de/preisvergleich/SubProductCategory/30311.html"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Computer",
      "item": "https://www.idealo.de/preisvergleich/SubProductCategory/1342.html"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Tablets",
      "item": "https://www.idealo.de/preisvergleich/ProductCategory/3747.html"
    }
  ]
}
</script>

Article

Pages tagged with Structured Data from Article have the option of being displayed in a sort of carousel in the search hits:

Here is an example code:

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Article",
  "image": "https://xc-ski.de/ein-bild.jpg",
  "publisher": {
    "@context": "http://schema.org",
    "@type": "Organization",
    "name": "xc-ski.de",
    "url": "https://xc-ski.de"
  },
  "author": {
    "@context": "http://schema.org",
    "@type": "Person",
    "name": "Mario F.",
    "url": "https://xc-ski.de/autoren/mario-f/",
  },
  "description": "Articles on the subject of cross-country skiing cup.",
  "datePublished": "2019-02-05T08:00:00+08:00",
  "headline": "44 victories in cross-country skiing World Cup: Johaug draws level with Väble in lricehamn"
}
</script>

Reviews

Reviews always get stars in the search results on Google. This is because the review is a kind of rating by nature. Therefore, a rating information is always mandatory in the snippet.

Currently, you can rate products, local businesses, music, recipes and books. Employers can also be rated via other child schemas such as EmployerReview.

Review schema in Googles search results.
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Review",
  "reviewRating": {
    "@context": "http://schema.org",
    "@type": "AggregateRating",
    "ratingValue": "5",
    "bestRating": "5",
    "reviewCount": "122",
    "worstRating": "1",
    "ratingCount": "122"
  },
  "itemReviewed": {
    "@context": "http://schema.org",
    "@type": "Product",
    "name": "SNIP"
  },
  "author": {
    "@context": "http://schema.org",
    "@type": "Person",
    "name": "Florian",
    "url": "https://rich-snippets.io"
  }
}
</script>

Carousels (ListItem)

Listings appear whenever you use the ItemList schema and then insert multiple ListItem child elements. An example can be found at chefkoch.de. Overview pages (with multiple recipes) are distinguished with an ItemList schema:

A carousel (ListItem) schema example on Google search results.
<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "url": "https://www.chefkoch.de/rezepte/940401199646006/Donuts.html",
      "name": "Donuts"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "url": "https://www.chefkoch.de/rezepte/1063831211703686/Mini-Donuts-fuer-den-Donut-Maker.html",
      "name": "Mini - Donuts für den Donut - Maker"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "url": "https://www.chefkoch.de/rezepte/629511163423946/Zimt-und-Zucker-Donuts.html",
      "name": "Zimt und Zucker Donuts"
    },
    {
      "@type": "ListItem",
      "position": 4,
      "url": "https://www.chefkoch.de/rezepte/574521156159933/Donuts-fuers-Backblech.html",
      "name": "Donuts fürs Backblech"
    },
    ...
  ]
}
</script>

There are even more

There are even more schema examples. Check out my list of snippet examples (that are for use in my plugin only).