WordPress
speaker schema
cheatsheet.
Every JSON-LD block a professional speaker's WordPress site should output — copy, paste, edit the placeholders. Bookmark-grade reference; comes up during every speaker site build I ship.
1. Person schema (goes on homepage + about page)
The single most important block. Google reads sameAs to build your Knowledge Panel entity graph — link every profile you own. Include Wikidata when you have an entry; that's the strongest single sameAs signal.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Jane Doe",
"jobTitle": "Keynote Speaker",
"url": "https://janedoe.com",
"image": "https://janedoe.com/headshot.jpg",
"sameAs": [
"https://www.linkedin.com/in/janedoe",
"https://x.com/janedoe",
"https://en.wikipedia.org/wiki/Jane_Doe",
"https://www.wikidata.org/wiki/Q123456789",
"https://www.youtube.com/@janedoe",
"https://www.ted.com/speakers/jane_doe"
],
"knowsAbout": [
"leadership",
"resilience",
"high-performance teams"
],
"alumniOf": {
"@type": "CollegeOrUniversity",
"name": "Stanford University"
}
}
</script>2. VideoObject (every talk page)
Use one per embedded talk. Google indexes videos as rich results and, more importantly, ties them to your Person entity when publisher.name matches your name or a stage brand (TEDx, SaaStr). uploadDate is required for rich-result eligibility.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "VideoObject",
"name": "The Resilience Advantage — TEDxDubai 2025",
"description": "A 15-minute talk on building teams that recover faster than they break.",
"thumbnailUrl": "https://janedoe.com/talks/tedx-dubai-thumb.jpg",
"uploadDate": "2025-11-14",
"duration": "PT14M52S",
"contentUrl": "https://www.youtube.com/watch?v=abc123",
"embedUrl": "https://www.youtube.com/embed/abc123",
"publisher": {
"@type": "Organization",
"name": "TEDx",
"logo": {
"@type": "ImageObject",
"url": "https://tedx.com/logo.png"
}
}
}
</script>3. Event (upcoming and past appearances)
Ship one per public speaking date. Past dates still count — they build entity depth. eventStatus values: EventScheduled, EventCancelled, EventPostponed, EventRescheduled, EventMovedOnline. eventAttendanceMode: OfflineEventAttendanceMode, OnlineEventAttendanceMode, or MixedEventAttendanceMode.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Event",
"name": "SaaStr Annual 2026 — Keynote by Jane Doe",
"startDate": "2026-09-10T09:00-07:00",
"endDate": "2026-09-10T10:00-07:00",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"eventStatus": "https://schema.org/EventScheduled",
"location": {
"@type": "Place",
"name": "San Jose Convention Center",
"address": {
"@type": "PostalAddress",
"streetAddress": "150 W San Carlos St",
"addressLocality": "San Jose",
"postalCode": "95113",
"addressCountry": "US"
}
},
"performer": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://janedoe.com"
},
"organizer": {
"@type": "Organization",
"name": "SaaStr"
}
}
</script>4. Book (author-speakers)
One per published book. Link author back to your Person schema via matching name + url. bookFormat can be Hardcover, Paperback, EBook, AudiobookFormat.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Book",
"name": "The Resilience Advantage",
"author": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://janedoe.com"
},
"isbn": "978-1-2345-6789-0",
"bookFormat": "https://schema.org/Hardcover",
"publisher": "Simon & Schuster",
"datePublished": "2025-04-08",
"image": "https://janedoe.com/book-cover.jpg"
}
</script>5. Service (booking / hire-me page)
Signals to Google that speaking is a service you sell. priceRange is optional but recommended — it filters out non-serious enquiries and Google increasingly surfaces it in results. Skip offers.price if you want to keep the number private and rely on priceRange for a band.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Keynote Speaking",
"name": "Keynote Speaking — Jane Doe",
"provider": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://janedoe.com"
},
"areaServed": [
"US",
"GB",
"EU",
"AE"
],
"audience": {
"@type": "Audience",
"audienceType": "Corporate leadership, conference organisers"
},
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"priceRange": "$25,000 – $50,000",
"availability": "https://schema.org/InStock"
}
}
</script>7. Common pitfalls
- Duplicate Person schema. Multiple plugins (Yoast, Rank Math, a theme's built-in SEO) each emit their own Person block. Google reads all of them and gets confused about your identity. Pick one source of truth and disable the rest.
- sameAs to profiles that don't link back. A LinkedIn URL in sameAs that doesn't have your site in its Contact section is a weak signal. Every sameAs relationship must be bidirectional to count.
- VideoObject without uploadDate. No rich result eligibility. Google silently ignores the block.
- Event schema for events that already happened, with no eventStatus. Google flags this in Search Console as a warning. Set eventStatus explicitly.
- Copy-pasting from another speaker's site. I've seen five speaker sites all shipping identical Person schema with a fake TEDx URL. Google notices. Ship your real profiles only.
- Trusting a schema plugin without validating. Every plugin I've audited emits at least one malformed field. Test every page at Google's Rich Results Test after any content change.
8. Wiring it into WordPress
Three paths, in order of preference:
- 1. Hand-coded mu-plugin. A must-use plugin that generates each block from page context (post type, ACF fields, custom taxonomies). No dashboard, no plugin update surprises, no bloat. This is what I ship on every speaker site.
- 2. Rank Math or Yoast schema editor. Second-best. Turn off their global Person and Organization blocks and hand-configure per page type. Validate everything.
- 3. A dedicated schema plugin (SchemaPress, Schema Pro). Only if you have no developer. Test every page after activation; expect duplicates.
Never rely on a page-builder's built-in schema toggle. Elementor, Divi, and Bricks all ship broken or overly generic markup that competes with your intentional schema.
“Schema is not decoration. It is how Google decides which entity a website is about. Get it wrong and you rank for nothing; get it right and you rank for your idea, not just your name.”
I ship every schema block above, wired to your content model, on every speaker site I build. Or as a standalone audit + implementation if your site is otherwise fine.