Structured data or schema are essentially HTML attributes or scripts that help search engines interpret the structure of specific content and understand how to display it correctly and prominently in search results (SERP’s).
Structured data is the standard format that search engines operate with, and they provide information about a specific page, helping search engines understand how to categorize that page.
For example, on a specific cooking recipe page, the information could include the ingredients, cooking time, desired temperature, calorie count, and more.
So, many of us have worked on WordPress websites or other projects where technical SEO was the first requirement, even before performing the process of On-page SEO.
These structured data are included in the execution of technical SEO for a website and can be crucial from this perspective, ultimately leading to better optimization and SEO performance.
Considering that not many bother to implement structured data on their websites, if done correctly, and assuming search engines decide to display them, you will have a certain advantage over your competitors – whether you’re managing a blog, selling products, advertising jobs, and so on.
In this guide, we will explain the concept behind structured data, look at possible formats, mention the advantages of using them, and then show how to add different types of data to WordPress websites without using plugins.
What Is Structured Data?
Structured data is a vocabulary of HTML attributes and values (or JSON scripts) that describe page content in a format search engines can parse. This markup goes into your site’s code and helps search engines crawl, index, and understand your content.
The idea of this lexicon, named Schema.org, was created through collaboration between Google, Microsoft, Yahoo, Yandex, and has been maintained by them as well as additional individuals from the W3C community.
You can actually see and participate in this community activity on the open community page.
The terms “structured data” and “schema” are often used interchangeably. Schema.org defines the vocabulary, while structured data is the broader concept of marking up content in a machine-readable format.
So, What Are Rich Snippets?
Schema markup is the code that powers enhanced search result features. Rich snippets are the visible result of using schema markup – they appear when Google decides that extra information would help users for a specific query.
Here’s an example of search results with rich snippets, one displaying recipes and the other books:
Schema Formats: Microdata vs JSON-LD
Schemas can be presented in three ways: Microdata, JSON-LD, and RDFa. In this guide, we’ll focus on Microdata and JSON-LD since they are the most common. In fact, as we delve into examples and see how to add schema markup to your WordPress pages, we’ll concentrate solely on JSON-LD.
Let’s see how the code differs between Microdata and JSON-LD for a specific business displaying its opening hours. Before we present the differences, see an example of a Google search result for this business (not necessarily relevant to the time of writing this article):

Notice how the address, phone number, and business hours appear in the search results. So here’s an example of how it’s done in both formats, noting that it’s just for demonstration purposes to show the code differences between the formats.
Using Microdata:
<div itemscope itemtype="http://schema.org/Pharmacy">
<h1 itemprop="name">Philippa's Pharmacy</h1>
<p itemprop="description">
A superb collection of fine pharmaceuticals.
</p>
<p>Open:
<span itemprop="openingHours" content="Mo,Tu,We,Th 09:00-12:00">
Monday-Thursday 9am-noon
</span>
</p>
</div>Similarly, this can be done using JSON-LD:
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Pharmacy",
"name": "Philippa's Pharmacy",
"description": "A superb collection of fine pharmaceuticals.",
"openingHours": "Mo,Tu,We,Th 09:00-12:00"
}
</script>Choosing Which Format to Use
Google’s structured data documentation recommends JSON-LD as the preferred format. JSON-LD is easier to maintain because it lives in a separate <script> tag and does not mix with your HTML markup.
How Schema Affects SEO
Does schema directly improve rankings? The answer is nuanced. Google has stated that structured data is not a direct ranking factor.
“If you add the relevant markup to your site pages, it doesn’t mean you’ll experience an improvement in your site’s ranking – but it helps Google and search engines understand your content better.”
However, schema helps Google surface your content in rich results, which can significantly increase your click-through rate (CTR). Pages with rich results can see CTR increases of 20-40%. Proper schema implementation will not hurt your rankings and is likely to improve visibility and user experience.
Supported Schema Types
The Google Search Gallery lists all supported schema types with implementation examples. You can also use the Structured Data Markup Helper to generate markup visually.
Here are the main content types Google supports:
- Articles
- Books
- Courses
- Datasets
- Events
- Job Posting
- Local Businesses
- Music
- Podcasts
- Products
- Recipes
- Reviews
- TV & Movies
- Fact Check
- FAQ
- HowTo
- Software Application
- Video
In addition to these content types, Google also checks structured data that enhances the user interface:
- Breadcrumbs
- Sitelinks Search Box
- Corporate Contact Information
- Logos
- Social Profile Links
- Carousels
Adding Schema Markup to WordPress
Below are code examples showing how to add JSON-LD schema to WordPress using PHP. These examples are from this blog and demonstrate the approach for different schema types.
SEO plugins like Yoast handle schema automatically and are a valid option for most sites. However, custom code gives you full control over the output – useful when you need precision for specific content types like local business hours or custom post types.
Note: The parameters shown below may not be relevant to your site. Consult the Google Search Gallery for the full list of supported properties for each schema type.
Structured data is a recommendation for search engines, not a guarantee of display. When deciding what to mark up, ask yourself: if this structured data were the only information a user saw, would it be useful?
Here are the code examples:
Adding BlogPosting Schema for Articles in the Blog
Here are examples of how I’m adding schema for various elements in the Savvy Blog. We’ll start with the BlogPosting schema, which is a more specific schema under the Article schema and is intended for all articles on this blog.
The way I do this is by adding JSON-LD to the head of the page in the following manner:
function json_ld_article() {
// Schema.org JSON for BlogPosting
// Only on single Posts & Snippets
if ( is_singular( 'post') || is_singular('snippet') ) {
// We need access to the post
global $post;
setup_postdata($post);
// Variables
$logo = get_template_directory_uri() . '/images/site-logo.png';
$logo_width = 82;
$logo_height = 60; // must be 60px and width <=600
$excerpt = get_the_excerpt();
$image = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
// Open script
$html = '<script type="application/ld+json">';
$html .= '{';
$html .= '"@context": "http://schema.org",';
$html .= '"@type": "BlogPosting",';
$html .= '"mainEntityOfPage": {';
$html .= '"@type": "WebPage",';
$html .= '"@id": "' . get_permalink() . '"';
$html .= '},';
// ... (rest of the schema markup)
$html .= '}';
// Close script
$html .= '</script>';
echo $html;
}
}
add_action('wp_footer', 'json_ld_article');Each schema uses the @type parameter to specify its type. The code uses standard WordPress functions like get_the_title(), get_permalink(), and get_the_author() to populate the schema dynamically. The is_singular() condition ensures the markup only loads on the relevant pages.
Adding Person Schema
This is a Person schema describing my name and several links to my social networks (referring to me personally as an individual and not as a company). This is just an example and is not implemented in this blog. Here’s the code you can use:
function json_ld_person() {
// Schema.org JSON for Person
$html = '<script type="application/ld+json">';
$html .= '{';
$html .= '"@context": "http://schema.org",';
$html .= '"@type": "Person",';
$html .= '"name": "Roee Yossef",';
$html .= '"url": "' . home_url() . '",';
$html .= '"sameAs" : [';
$html .= '"https://www.facebook.com/roee.yossef/",';
$html .= '"https://x.com/RoeeYossef",';
$html .= '"https://www.linkedin.com/in/roeeyossef/"';
$html .= ']}';
// Close script
$html .= '</script>';
echo $html;
}
add_action('wp_head', 'json_ld_person');Adding Organization Schema
This schema is of type Organization and relates to the company’s blog. Similar to Person, in this code, I specify the links to the social networks of the company’s blog as well as the logo and the blog’s name.
The choice of whether to add a Person or Organization schema depends on your website’s nature and is up to you. As far as I know, the correct approach is to add only one of the two options. If you are familiar with Yoast, you probably know that it also allows you to choose only one option, either a company or an individual.
function json_ld_organization() {
// Schema.org JSON for Organization
$logo = get_template_directory_uri() . '/images/site-logo.png';
$logo_width = 82;
$logo_height = 60;
// Open script
$html = '<script type="application/ld+json">';
$html .= '{';
$html .= '"@context" : "http://schema.org",';
$html .= '"@type" : "Organization",';
$html .= '"name" : "' . get_bloginfo( 'name' ) . '",';
$html .= '"url" : "' . home_url() . '",';
$html .= '"logo": {';
$html .= '"@type": "ImageObject",';
$html .= '"url": "' . $logo . '",';
$html .= '"width": ' . $logo_width . ',';
$html .= '"height": ' . $logo_height;
$html .= '},';
$html .= '"sameAs" : [';
$html .= '"https://www.facebook.com/savvy.wordpress/",';
$html .= '"https://x.com/Wordpress_Savvy"';
$html .= ']}';
// Close script
$html .= '</script>';
echo $html;
}
add_action('wp_head', 'json_ld_organization');Note that Organization schema should not be embedded on every page.
Adding WebSite Schema
This is a WebSite schema describing the website’s name (Savvy Blog), an alternative name, and its URL. This schema is broad and covers the entire site.
function json_ld_website() {
// Schema.org JSON for WebSite
$html = '<script type="application/ld+json">';
$html .= '{';
$html .= '"@context": "http://schema.org",';
$html .= '"@type": "WebSite",';
$html .= '"name": "' . get_bloginfo( 'name' ) . '",';
$html .= '"alternateName": "Savvy Blog",';
$html .= '"url": "' . home_url() . '"';
$html .= '}';
// Close script
$html .= '</script>';
echo $html;
}
add_action('wp_head', 'json_ld_website');Adding BreadCrumbs Schema
This is a BreadCrumbs schema responsible for the breadcrumbs displayed when a result from this blog appears in search engines.

The code in this case is slightly different from the code necessary for category breadcrumbs as in this case we use a different taxonomy.
function json_ld_breadcrumbs() {
// Schema.org JSON for breadcrumbs
if ( is_singular( 'post') || is_singular('snippet') ) {
global $post;
$post_terms = wp_get_object_terms($post->ID, 'taxonomy', array('fields'=>'ids'));
$term_name = get_term( $post_terms[0], 'taxonomy') ;
$html = '<script type="application/ld+json">';
$html .= '{';
$html .= '"@context": "http://schema.org",';
$html .= '"@type": "BreadcrumbList",';
$html .= '"itemListElement": [';
$html .= '{';
$html .= '"@type": "ListItem",';
$html .= '"position": "1",';
$html .= '"item" : {';
$html .= '"@id" : "' . get_site_url() . '",';
$html .= '"name": "' . get_bloginfo( 'name' ) . '"';
$html .= '}},';
$html .= '{';
$html .= '"@type": "ListItem",';
$html .= '"position": "2",';
$html .= '"item" : {';
$html .= '"@id" : "' . $term_name->term_id . '",';
$html .= '"name" : "' . $term_name->name . '"';
$html .= '}},';
$html .= '{';
$html .= '"@type": "ListItem",';
$html .= '"position": "3",';
$html .= '"item" : {';
$html .= '"@id" : "' . get_permalink() . '",';
$html .= '"name" : "' . get_the_title() . '"';
$html .= '}}]}';
// Close script
$html .= '</script>';
echo $html;
}
}
add_action( 'wp_head', 'json_ld_breadcrumbs' );Since Yoast automatically adds schema markup based on your plugin settings, you may need to filter its JSON-LD output.
For Yoast versions below 11.0, you can remove the schema using the following filter:
function savvy_remove_yoast_json($data){
$data = array();
return $data;
}
add_filter('wpseo_json_ld_output', 'savvy_remove_yoast_json', 10, 1);For Yoast versions higher than 11.0, you can use this filter:
add_filter( 'wpseo_json_ld_output', '__return_false' );With that, the code examples are complete. You can validate your schema using the Rich Results Test or the Schema Markup Validator.
FAQs
Summary
Structured data helps search engines understand your content and can unlock rich results that boost CTR. JSON-LD is the recommended format and can be added to WordPress using PHP functions hooked to wp_head or wp_footer.
Start with the essentials – Article, Organization, BreadcrumbList, and WebSite schema – then expand to content-specific types like FAQPage, HowTo, or Product as needed. Use the Rich Results Test to validate your markup.
For recipe-specific schema, see our guide on adding structured data to recipe sites. You can also use Advanced Custom Fields to let clients edit schema properties through the WordPress admin.
Schema is also becoming critical for AI search. To learn which types matter most for AI Overviews and generative search engines, see my guide on schema markup for AI search.



