The SEO Framework · KB

★︎ Start with TSF
  • Extensions
  • Documentation
  • Pricing
  1. Home
  2. Knowledge Base
  3. Structured data supported by The SEO Framework

Structured data supported by The SEO Framework — Contents

  • Implemented data types
  • Don’t overdo it
  • How the output works
    • Extension scripts
  • Example output
    • Core graph
    • Articles extension
    • Local SEO extension
  • Testing
  • Other sources
  • Customizing the graph

Structured data supported by The SEO Framework

Published on May 27, 2019
Revised on March 27, 2026

Structured data helps search engines and AI systems interpret your WordPress site. TSF outputs structured data in the Schema.org JSON-LD format. These invisible <script> blocks in your page’s <head> work with every theme and plugin.

Search engines combine all structured data on a page to create a single picture of that page and its website. Multiple plugins, your theme, and inline markup all contribute. Their outputs complement each other because they all describe the same webpage. If two sources conflict on the same property, search engines use the first occurrence. You do not need to disable other plugins’ structured data for TSF to work correctly, or vice versa.

TSF draws most of its structured data from your existing WordPress content—titles, descriptions, dates, author profiles, permalinks, content hierarchy, and site settings. Some types offer toggles or dedicated fields, but the bulk of the markup is generated automatically from your content.

Implemented data types

TSF‘s product family implements these types. Google lists all supported types in their structured data reference. We output as many as Google’s structured data policies allow.

  • Article:
    • Delivered via the Articles extension.
    • Affected pages: Only outputted on posts that meet all requirements, not pages.
    • Annotation: The post’s headline, description, publishing and updated time, author, and publisher.
    • Usefulness: Binds sites with the same authors together. News publishers benefit from Carousel (see below).
  • Breadcrumb:
    • TSF delivers this type.
    • How to enable: Enable “Output structured data” and “Add breadcrumbs” in SEO Settings → Schema.org Settings → General. Set title preferences in SEO Settings → Schema.org Settings → Breadcrumbs. That tab also manages the breadcrumb shortcode.
    • Affected pages: All singular post types.
    • Annotation: The page’s URL hierarchy.
    • Usefulness: Prominently displayed in search engines. Helps visitors and search engines understand your site’s hierarchy.
  • Carousel:
    • Delivered via the Articles extension.
    • Affected pages: Same as Article.
    • Annotation: Implied by Article. Google’s documentation does not explicitly list “news articles” for the carousel, even though it does exist for this type.
    • Usefulness: Higher click-through rates on contemporary content, like news articles.
  • Organization (parent type of LocalBusiness):
    • TSF delivers this type.
    • How to enable: Enable “Output structured data” and “Add authorized presence” in SEO Settings → Schema.org Settings → General. Expanded by the Local SEO extension.
    • Affected pages: Only the homepage. With Local SEO, also every matched department URL.
    • Annotation: Only for sites representing an Organization: name, logo, and connected social networks. More details with the Local SEO extension.
    • Usefulness: Prominent brand display. Only reputable, well-established websites benefit.
  • Local Business (subtype of Organization):
    • Delivered via the Local SEO extension.
    • Affected pages: The homepage and every matched department URL.
    • Annotation: Business type, opening hours, contact details, and more.
    • Usefulness: Prominent brand display. Only trusted websites benefit well. Google Business Profile helps build that trust.
  • Logo:
    • TSF delivers this type.
    • How to enable: Enable “Output structured data” and “Add authorized presence” in SEO Settings → Schema.org Settings → General, set the site to represent an Organization, and enable “Add logo” in SEO Settings → Schema.org Settings → Presence.
    • Affected pages: Only the homepage, via the Organization entity.
    • Annotation: Included via the Organization entity. Google may not report this type separately in Google Search Console because it is part of a graph. This is an issue on Google’s end.
    • Usefulness: Little to none. Most logos displayed in search are taken from Wikipedia, not structured data.
  • Sitelinks Search Box (deprecated by Google):
    • TSF delivers this type.
    • How to enable: Enable “Output structured data” and “Add Sitelinks Search Box” in SEO Settings → Schema.org Settings → General.
    • Affected pages: All pages.
    • Annotation: A SearchAction pointing to the WordPress search endpoint, included in the WebSite entity. The WebSite entity itself (site name, description, URL) is always output regardless of this toggle.
    • Usefulness: Google removed this feature from search results. The SearchAction may still be used by other consumers, but Google no longer displays it.
    • Note: Google crawls anything that looks like a URL, including the urlTemplate value of this data type. The URL template is a literal search query for {search_term_string}, which will show up in your Google Search Console’s Page indexing report under “Excluded by ‘noindex’ tag”. You can safely ignore this entry in the report.
  • Social Profile (undocumented by Google):
    • TSF delivers this type.
    • How to enable: Enable “Output structured data” in SEO Settings → Schema.org Settings → General.
    • Affected pages: On singular posts (author level) and all pages when “Add authorized presence” is enabled (site level).
    • Annotation for authors: The author’s X and Facebook links from their WordPress profile, added as sameAs URLs on the author Person entity.
    • Annotation for the site: Social profile URLs from SEO Settings → Schema.org Settings → Presence, added as sameAs URLs on the Organization or Person entity (depending on which the site represents). This covers Facebook, X, Instagram, YouTube, LinkedIn, Pinterest, SoundCloud, and Tumblr.
    • Usefulness: Prominent social links display. Only reputable, well-established websites benefit.

Don’t overdo it

Not all structured data is useful — we intentionally exclude types that add no value. We never implemented HowTo or FAQ markup because Google was already pushing back on abuse in 2020. Three years later, they removed both rich result types entirely — yet many SEO plugins still output them.

Some properties are redundant too: inLanguage in our WebSite and WebPage entities duplicate the <html lang="ll-CC"> attribute — we added this only because we already had the data.

Structured data is powerful, but you must follow Google’s strict policies to be eligible for rich results. Violating those policies flags your site for spam. We give users minimal control over the markup to prevent this. We also stay clear of Review snippet markup — it is often abused, and we hate encountering it in the wild.

About AI: Large language models can read structured data, but they also read your entire page. Structured data supplements good content; it does not replace it. Adding more types will not meaningfully change how AI interprets your site.

How TSF outputs structured data

Since version 5.0, TSF outputs a single JSON-LD <script> block containing a Schema.org graph — a collection of linked entities. Each entity has an @id that other entities can reference, so search engines understand how your WebSite, WebPage, Organization, and other types relate to each other.

What appears in the graph depends on the page type, your settings, and whether the site represents an Organization or a Person. On archive pages, the WebPage type becomes CollectionPage. On search results pages, it uses both CollectionPage and SearchResultsPage.

Extension scripts

The Articles and Local SEO extensions output their schemas as separate <script> blocks alongside TSF’s main graph. This is by design: Google and other JSON-LD consumers process all <script type="application/ld+json"> blocks on a page together.

The Articles extension connects its output to the main graph by referencing the page’s canonical URL in mainEntityOfPage, which matches the @id of TSF’s WebPage entity. Entities without an explicit @id are treated as anonymous nodes in JSON-LD — they don’t inherit the current page URL.

Example output

Below are representative examples of what TSF outputs. The properties depend on your settings, site presence type, and the page being viewed. TSF outputs minified JSON by default; these are formatted for readability.

TSF core graph (singular post)

This example shows the output on a blog post, on a site representing an Organization, with breadcrumbs and sitelinks searchbox enabled:

{
	"@context": "https://schema.org",
	"@graph": [
		{
			"@type": "WebSite",
			"@id": "https://example.com/#/schema/WebSite",
			"url": "https://example.com",
			"name": "Example Blog",
			"description": "A blog about web development and SEO.",
			"inLanguage": "en-US",
			"potentialAction": {
				"@type": "SearchAction",
				"target": {
					"@type": "EntryPoint",
					"urlTemplate": "https://example.com/?s={search_term_string}"
				},
				"query-input": "required name=search_term_string"
			},
			"publisher": {
				"@id": "https://example.com/#/schema/Organization"
			}
		},
		{
			"@type": "WebPage",
			"@id": "https://example.com/blog/optimized-structured-data/",
			"url": "https://example.com/blog/optimized-structured-data/",
			"name": "Optimized Structured Data",
			"description": "How to inspect and customize your site's structured data.",
			"inLanguage": "en-US",
			"isPartOf": {
				"@id": "https://example.com/#/schema/WebSite"
			},
			"breadcrumb": {
				"@id": "https://example.com/#/schema/BreadcrumbList"
			},
			"datePublished": "2025-09-10T08:00:00+00:00",
			"dateModified": "2026-03-27T12:30:00+00:00",
			"author": {
				"@id": "https://example.com/#/schema/Person/a1b2c3d4e5f6"
			},
			"potentialAction": {
				"@type": "ReadAction",
				"target": "https://example.com/blog/optimized-structured-data/"
			}
		},
		{
			"@type": "BreadcrumbList",
			"@id": "https://example.com/#/schema/BreadcrumbList",
			"itemListElement": [
				{
					"@type": "ListItem",
					"position": 1,
					"item": "https://example.com",
					"name": "Home"
				},
				{
					"@type": "ListItem",
					"position": 2,
					"item": "https://example.com/blog/",
					"name": "Blog"
				},
				{
					"@type": "ListItem",
					"position": 3,
					"name": "Optimized Structured Data"
				}
			]
		},
		{
			"@type": "Organization",
			"@id": "https://example.com/#/schema/Organization",
			"name": "Example Corp",
			"url": "https://example.com",
			"logo": {
				"@type": "ImageObject",
				"url": "https://example.com/wp-content/uploads/logo.png",
				"contentUrl": "https://example.com/wp-content/uploads/logo.png",
				"width": 600,
				"height": 200,
				"inLanguage": "en-US",
				"caption": "Example Corp Logo"
			},
			"sameAs": [
				"https://www.facebook.com/example",
				"https://www.linkedin.com/company/example"
			]
		},
		{
			"@type": "Person",
			"@id": "https://example.com/#/schema/Person/a1b2c3d4e5f6",
			"name": "J. Doe",
			"description": "Web developer and technical writer.",
			"sameAs": [
				"https://www.linkedin.com/in/example-author"
			]
		}
	]
}

Every entity has an @id that other entities reference. The WebPage points to the WebSite via isPartOf, to the BreadcrumbList via breadcrumb, and to the author Person via author. The WebSite points to the Organization via publisher. If the same entity is referenced multiple times, TSF writes it once in the graph and uses @id pointers elsewhere.

Articles extension output

The Articles extension adds a separate script for Article markup on qualifying posts:

{
	"@context": "https://schema.org",
	"@type": "Article",
	"headline": "Optimized Structured Data",
	"image": {
		"@type": "ImageObject",
		"url": "https://example.com/wp-content/uploads/optimized-structured-data.jpg",
		"width": 1200,
		"height": 630
	},
	"datePublished": "2025-09-10T08:00:00+00:00",
	"dateModified": "2026-01-15T12:30:00+00:00",
	"author": {
		"@type": "Person",
		"name": "J. Doe",
		"url": "https://example.com/author/j-doe/"
	},
	"publisher": {
		"@type": "Organization",
		"name": "Example Corp",
		"logo": {
			"@type": "ImageObject",
			"url": "https://example.com/wp-content/uploads/logo-rect.jpg",
			"width": 600,
			"height": 60
		}
	},
	"description": "How to inspect and customize your site's structured data.",
	"mainEntityOfPage": {
		"@type": "WebPage",
		"@id": "https://example.com/blog/optimized-structured-data/"
	}
}

The mainEntityOfPage.@id matches the WebPage.@id in the core graph above. This tells search engines that this Article is the main content of that WebPage — even though the two scripts are separate.

Local SEO extension output

The Local SEO extension outputs LocalBusiness schema as a separate script. The exact properties depend on the department type and your settings. A basic LocalBusiness might include only an address, coordinates, and opening hours. A Restaurant adds cuisine, menu, and reservation details. Every empty property is omitted from the output.

This example shows a restaurant-type department with most properties populated:

{
	"@context": "https://schema.org",
	"@type": "Restaurant",
	"image": "https://example.com/wp-content/uploads/storefront.jpg",
	"name": "The Leaky Cauldron",
	"address": {
		"@type": "PostalAddress",
		"streetAddress": "Bull's Head Passage 42",
		"addressLocality": "London",
		"addressRegion": "England",
		"postalCode": "EC3V 1LT",
		"addressCountry": "GB"
	},
	"geo": {
		"@type": "GeoCoordinates",
		"latitude": 51.5124785,
		"longitude": -0.083968
	},
	"url": "https://example.com/",
	"telephone": "+442071234567",
	"menu": "https://example.com/menu/",
	"servesCuisine": ["British", "Belgian"],
	"priceRange": "$$",
	"openingHoursSpecification": [
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": [
				"Monday",
				"Tuesday",
				"Wednesday",
				"Thursday",
				"Friday"
			],
			"opens": "11:00",
			"closes": "22:00"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": ["Saturday"],
			"opens": "10:00",
			"closes": "23:00"
		},
		{
			"@type": "OpeningHoursSpecification",
			"dayOfWeek": ["Sunday"],
			"opens": "0:00",
			"closes": "0:00"
		}
	],
	"acceptsReservations": true,
	"potentialAction": {
		"@type": "ReserveAction",
		"target": {
			"@type": "EntryPoint",
			"url": "https://example.com/reserve/",
			"inLanguage": "en-GB"
		},
		"result": {
			"@type": "FoodEstablishmentReservation",
			"name": "Reserve a table"
		}
	}
}

A plain LocalBusiness (e.g., a retail store) would omit menu, servesCuisine, acceptsReservations, and potentialAction — those are exclusive to food-establishment types. Opening hours entries can also carry validFrom and validThrough dates for seasonal schedules.

Testing your structured data

Google provides two tools for inspecting structured data. Both accept a URL or pasted JSON-LD.

  • Rich Results Test — tests whether your markup qualifies for Google’s rich result features. This tool reflects Google’s opinion on the implementation: it shows warnings, errors, and which rich results you are eligible for. TSF targets this tool’s requirements.
  • Schema.org Validator — validates raw Schema.org markup against the specification. No opinion from Google — just whether the data conforms to Schema.org’s vocabulary. Passing validation here does not guarantee rich results.

Use the Rich Results Test first. If your markup passes there, it meets Google’s requirements. The Schema.org Validator is a secondary reference for debugging structural issues.

Other structured data on your site

TSF is not the only source of structured data on your WordPress site. Many themes annotate markup using inline formats such as Microdata or RDFa. Plugins add their own JSON-LD too — WooCommerce, for example, outputs Product markup on product pages.

JSON-LD blocks are processed independently, and inline Microdata is separate from JSON-LD entirely.

Developers: Customizing the graph

TSF provides three filter hooks for modifying the graph. They fire in this order:

  1. the_seo_framework_schema_entity_builders — add or remove entity builder callbacks before the graph is assembled.
  2. the_seo_framework_schema_queued_graph_data (since TSF 5.1) — modify the graph before dynamic references are resolved. Use this when working with the Reference class.
  3. the_seo_framework_schema_graph_data — modify the final graph before output. Use this for most customizations.

All three pass a sequential array of entity arrays and the query arguments ($args, which accepts id, tax, pta, and uid, or null when autodetermined).

This example reads a video URL from post meta and adds it to the WebPage entity:

add_filter(
	'the_seo_framework_schema_graph_data',
	function ( $graph, $args ) {

		if ( ! tsf()->query()->is_singular() )
			return $graph;

		// This assumes custom fields "_video_url" and "_video_title" on the post.
		$post_id     = tsf()->query()->get_the_real_id();
		$video_url   = get_post_meta( $post_id, '_video_url', true );
		$video_title = get_post_meta( $post_id, '_video_title', true );

		if ( ! $video_url || ! $video_title )
			return $graph;

		foreach ( $graph as &$entity ) {
			// Target the WebPage entity. The @type can be a string or an array.
			if ( in_array(
				'WebPage',
				(array) ( $entity['@type'] ?? [] ),
				true,
			) ) {
				$entity['video'] = [
					'@type'      => 'VideoObject',
					'name'       => tsf()->sanitize()->metadata_content( $video_title ),
					'contentUrl' => sanitize_url( $video_url, [ 'https', 'http' ] ),
				];
				break;
			}
		}

		return $graph;
	},
	10,
	2,
);

The VideoObject is inlined on the WebPage entity. If the same entity needs to appear in multiple places, give it an @id and add it as a separate entry in the $graph array — then reference it elsewhere with [ '@id' => $id ]. That’s the same linking mechanism TSF uses internally.

For entities that appear in multiple places, extend The_SEO_Framework\Meta\Schema\Entities\Reference — TSF handles @id deduplication automatically. See this ImageObject snippet for a working example.

Filed Under: Features, Structured Data

Related articles

  • Features

    • Advanced Query Protection
    • Robots.txt blocks
    • Breadcrumb shortcode
    • All you must know about sitemaps
    • Explaining the description generator
  • Structured Data

    • WooCommerce integration

Commercial

The SEO Framework
Trademark of CyberWire B.V.
Leidse Schouw 2
2408 AE Alphen a/d Rijn
The Netherlands
KvK: 83230076
BTW/VAT: NL862781322B01

Twitter  GitHub

Professional

Pricing
About
Support
Terms and Conditions
Refund Policy

Editorial

Knowledge Base
Release Notes
Feature Highlights
Blog
Privacy Policy

Practical

TSF on WordPress
TSF on GitHub
TSFEM on here
TSFEM on GitHub
Deploy Troy

Share music in 2026 › The SEO Framework