The mental model
A web page is a document. A search engine crawler looks at it and tries to guess: is this an article? A product? A person's homepage? A recipe? That guess drives which "rich" treatments are available in the search results.
Schema.org is the shared vocabulary you use to stop making the crawler guess. You declare, in machine-readable JSON, exactly what each thing on the page is and how the things relate. Crawlers don't have to infer — they know.
What you get out of it
- Rich snippets — star ratings, FAQ dropdowns, breadcrumb trails, event dates, recipe thumbnails, price ranges, job postings with salary.
- Knowledge panel eligibility — for organisations and public figures, the sidebar card in Google search is fed partly by Organization / Person schema plus
sameAslinks. - Clearer entity understanding — Google's systems link your author to your articles to your organisation, which feeds E-E-A-T interpretation.
- AI / assistant surface area — LLM-powered search and chat clients increasingly lean on structured data when extracting answers and attributions.
Why JSON-LD beats microdata
Schema.org markup can be delivered three ways: JSON-LD, microdata, or RDFa. Google officially supports all three; in practice, use JSON-LD.
- It lives in a single
<script>tag in the head. You can edit it without touching page HTML. - It's what Google explicitly recommends.
- It's easy to template and version-control.
- It doesn't make you put
itempropattributes on every<span>.
All examples below are JSON-LD.
Organization schema
Organization schema is the "who runs this site" declaration. For a company, agency, or business, this is almost always the right root entity.
Place this in <head> on your homepage, and reference it from every other page via @id.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example Co.",
"url": "https://example.com/",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png",
"width": 512,
"height": 512
},
"sameAs": [
"https://www.linkedin.com/company/example",
"https://twitter.com/example",
"https://www.youtube.com/@example"
],
"contactPoint": [{
"@type": "ContactPoint",
"contactType": "customer support",
"email": "hello@example.com",
"areaServed": "AU",
"availableLanguage": ["English"]
}],
"address": {
"@type": "PostalAddress",
"addressLocality": "Sydney",
"addressRegion": "NSW",
"addressCountry": "AU"
}
}
</script>
The sameAs array is one of the highest-leverage properties in all of schema. It's how you tell Google "these other profiles on the internet are this same entity." That's the mechanism behind knowledge panels appearing, and it's how Google fuses your reputation across platforms.
Person schema (for solo sites)
If the site is a personal brand or solo operator, use Person instead of (or alongside) Organization. For this site, Person is the root entity — there's no company behind it, just me.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"@id": "https://anthonyligyat.com/#person",
"name": "Anthony Ligyat",
"jobTitle": "Growth Marketing Consultant",
"url": "https://anthonyligyat.com/",
"image": "https://anthonyligyat.com/anthony.jpg",
"description": "Sydney-based growth marketing consultant. Nine months in-house at Excelerate Consulting; now building the international brand for Yuan Packaging.",
"sameAs": [
"https://www.linkedin.com/in/anthonyligyat/"
],
"alumniOf": [
{ "@type": "CollegeOrUniversity", "name": "UNSW Sydney" }
],
"knowsAbout": [
"AI marketing automation",
"Ebook lead funnels",
"International SEO",
"GA4"
],
"address": {
"@type": "PostalAddress",
"addressLocality": "Sydney",
"addressRegion": "NSW",
"addressCountry": "AU"
}
}
</script>
knowsAbout lets you declare topical expertise without stuffing your bio. alumniOf adds a formal-credential signal. sameAs does the reputation-fusing work described above.
WebSite schema
WebSite schema declares the site itself as an entity, separate from its owner. It also lets you wire in a SearchAction so Google can show a sitelinks search box under your homepage in results.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"@id": "https://example.com/#website",
"url": "https://example.com/",
"name": "Example",
"publisher": { "@id": "https://example.com/#organization" },
"inLanguage": "en-AU",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
</script>
Skip the SearchAction if you don't have an on-site search. Keep the rest.
Article schema
On any page that's a proper article (blog post, guide, long-form), add Article schema. This is the main piece that unlocks Article-style rich snippets — bylines in SERPs, "top stories" eligibility, AI-search attribution.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"@id": "https://example.com/blog/my-post.html#article",
"mainEntityOfPage": "https://example.com/blog/my-post.html",
"headline": "My post's headline, exactly as shown",
"description": "One-sentence description, ≤160 chars.",
"image": "https://example.com/my-post-hero.png",
"author": {
"@type": "Person",
"@id": "https://example.com/#person",
"name": "Jane Doe",
"url": "https://example.com/about.html"
},
"publisher": { "@id": "https://example.com/#organization" },
"datePublished": "2026-04-24",
"dateModified": "2026-05-21",
"articleSection": "SEO",
"inLanguage": "en-AU",
"keywords": "Schema.org, JSON-LD, Rich Snippets"
}
</script>
Two things matter most here: (1) author is an object with a real Person, ideally referencing the same @id as the one on your About / homepage; (2) datePublished and dateModified are real and match what's visible on the page.
BreadcrumbList schema
BreadcrumbList is the one that earns you that clean Home › Category › Article trail in the search result instead of a raw URL. Quick win on any multi-page site.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"@id": "https://example.com/blog/my-post.html#breadcrumb",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home",
"item": "https://example.com/" },
{ "@type": "ListItem", "position": 2, "name": "Blog",
"item": "https://example.com/blog/" },
{ "@type": "ListItem", "position": 3, "name": "My post",
"item": "https://example.com/blog/my-post.html" }
]
}
</script>
Keep the breadcrumb structure consistent with what's actually shown on the page and in the URL. Don't invent a taxonomy that doesn't exist.
Tying it all together with @graph
On your homepage, the cleanest pattern is a single @graph block containing the Organization (or Person), the WebSite, and the WebPage, with @id references wiring them together.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Person",
"@id": "https://anthonyligyat.com/#person",
"name": "Anthony Ligyat",
"url": "https://anthonyligyat.com/",
"sameAs": ["https://www.linkedin.com/in/anthonyligyat/"]
},
{
"@type": "WebSite",
"@id": "https://anthonyligyat.com/#website",
"url": "https://anthonyligyat.com/",
"name": "Anthony Ligyat",
"publisher": { "@id": "https://anthonyligyat.com/#person" },
"inLanguage": "en-AU"
},
{
"@type": "WebPage",
"@id": "https://anthonyligyat.com/#home",
"url": "https://anthonyligyat.com/",
"name": "Anthony Ligyat — Marketing, measured.",
"isPartOf": { "@id": "https://anthonyligyat.com/#website" },
"about": { "@id": "https://anthonyligyat.com/#person" }
}
]
}
</script>
The @ids aren't URLs to fetch — they're stable identifiers. Using the canonical URL plus a fragment (#person, #website) is the convention. It makes the graph easy to debug and easy to extend.
How to validate
Before you ship markup, run it through at least one of these:
- Google Rich Results Test — tells you which rich-result types your page is eligible for, and catches errors.
- Schema.org Validator — pure validation against the vocabulary, no Google opinion layered on.
- Google Search Console's Enhancements report — once the page is live and indexed, this flags structured-data errors across the site.
The Rich Results Test will also show you the rendered snippet preview — useful for checking that your headline, image, and byline look right before you commit.
Common mistakes
Marking up things that aren't on the page. The structured data has to match what users actually see. FAQ schema without an actual FAQ on the page will get your site a manual action, not more traffic.
Inflating dates. Changing dateModified every day without real content changes is a tell Google catches quickly, and it can suppress freshness signals entirely.
Fake reviews. Self-serving AggregateRating markup gets penalised. Use genuine reviews from a proper review platform.
Orphaned @ids. If your Article references an author @id that doesn't exist anywhere else on your site, the wiring is broken. Keep the Person or Organization definition consistent across pages.
Stuffing types. A single entity declared as "@type": ["Organization", "Person", "LocalBusiness", "Corporation"] confuses crawlers and adds nothing.