Schema.org
6 min read
Collaborative structured data vocabulary backed by Google, Microsoft, Yahoo, and Yandex. Defines a hierarchy of types (Thing → CreativeWork → Article) with properties for annotating web content so search engines and other systems can understand it.
Type Hierarchy
Everything extends Thing. Major branches:
| Branch | Examples |
|---|---|
CreativeWork | Article, Book, Movie, Recipe, SoftwareApplication, WebPage, VideoObject |
Event | Event, MusicEvent, SportsEvent, CourseInstance |
Organization | Corporation, LocalBusiness, EducationalOrganization, NGO |
Person | Person |
Place | Place, LocalBusiness, PostalAddress, GeoCoordinates |
Intangible | Offer, Rating, Brand, Service, Role, Audience |
Action | SearchAction, BuyAction, ViewAction |
MedicalEntity | Drug, MedicalCondition, MedicalProcedure |
Product | Product, Vehicle, IndividualProduct |
Google Rich Results
These types unlock enhanced search appearance when embedded as JSON-LD in HTML:
| Type | Rich result |
|---|---|
Article / NewsArticle / BlogPosting | Top stories carousel, headline |
Product + Offer | Product snippet, price, availability |
AggregateRating + Review | Star ratings in results |
Recipe | Recipe card with image, time, rating |
Event | Event listing with date and location |
FAQPage | Expandable Q&A below the result |
HowTo | Step-by-step inline result |
JobPosting | Job listing card |
LocalBusiness | Knowledge panel with hours, map |
BreadcrumbList | Breadcrumb trail below URL |
VideoObject | Video thumbnail, duration, key moments |
Course | Course carousel |
Dataset | Dataset in Google Dataset Search |
SoftwareApplication | App rating and price |
Organization | Logo in knowledge panel |
WebSite + SearchAction | Sitelinks search box |
Validate at search.google.com/test/rich-results and validator.schema.org.
ImageObject
json
{
"@type": "ImageObject",
"url": "https://example.com/photo.jpg",
"width": 1200,
"height": 630
}
PostalAddress
json
{
"@type": "PostalAddress",
"streetAddress": "123 Main St",
"addressLocality": "Berlin",
"addressRegion": "BE",
"postalCode": "10115",
"addressCountry": "DE"
}
Person
json
{
"@type": "Person",
"name": "Angelo",
"url": "https://example.com/angelo",
"sameAs": ["https://twitter.com/angelo", "https://github.com/angelo"]
}
Organization
json
{
"@type": "Organization",
"name": "Acme Corp",
"url": "https://acme.com",
"logo": { "@type": "ImageObject", "url": "https://acme.com/logo.png" },
"sameAs": ["https://linkedin.com/company/acme"]
}
Article / BlogPosting / NewsArticle
No required properties — all recommended:
| Property | Type | Notes |
|---|---|---|
headline | Text | Article title, ≤110 chars |
author | Person / Organization | Can be an array |
datePublished | DateTime | ISO 8601 |
dateModified | DateTime | ISO 8601 |
image | ImageObject / URL | Multiple aspect ratios recommended (16:9, 4:3, 1:1) |
publisher | Organization | Include logo |
description | Text | Summary |
articleBody | Text | Full text |
json
{
"@context": "https://schema.org/",
"@type": "Article",
"headline": "My Article Title",
"author": {
"@type": "Person",
"name": "Angelo",
"url": "https://example.com/angelo"
},
"publisher": {
"@type": "Organization",
"name": "My Site",
"logo": { "@type": "ImageObject", "url": "https://example.com/logo.png" }
},
"datePublished": "2024-01-15T08:00:00+01:00",
"dateModified": "2024-02-01T12:00:00+01:00",
"image": [
"https://example.com/photo-16x9.jpg",
"https://example.com/photo-4x3.jpg",
"https://example.com/photo-1x1.jpg"
]
}
Product
| Property | Required | Notes |
|---|---|---|
name | ✓ | |
image | ✓ | |
offers | — | Offer or AggregateOffer |
aggregateRating | — | |
review | — | |
brand | — | Brand or Organization |
sku | — | Stock keeping unit |
gtin | — | EAN/UPC barcode |
description | — |
json
{
"@context": "https://schema.org/",
"@type": "Product",
"name": "Widget Pro",
"image": "https://example.com/widget.jpg",
"brand": { "@type": "Brand", "name": "Acme" },
"sku": "WGT-001",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "89"
},
"offers": {
"@type": "Offer",
"price": "29.99",
"priceCurrency": "EUR",
"availability": "https://schema.org/InStock",
"url": "https://example.com/buy",
"priceValidUntil": "2024-12-31"
}
}
availability values: InStock, OutOfStock, PreOrder, BackOrder, Discontinued — all prefixed with https://schema.org/.
Event
| Property | Required | Notes |
|---|---|---|
name | ✓ | |
startDate | ✓ | ISO 8601 with time |
location | ✓ | Place with PostalAddress |
endDate | — | |
description | — | |
image | — | |
offers | — | Ticket Offer |
organizer | — | Organization or Person |
performer | — | Person or PerformingGroup |
eventStatus | — | EventScheduled / EventCancelled / EventPostponed / EventRescheduled |
eventAttendanceMode | — | OfflineEventAttendanceMode / OnlineEventAttendanceMode / MixedEventAttendanceMode |
json
{
"@context": "https://schema.org/",
"@type": "Event",
"name": "Tech Meetup Berlin",
"startDate": "2024-03-15T19:00:00+01:00",
"endDate": "2024-03-15T22:00:00+01:00",
"eventStatus": "https://schema.org/EventScheduled",
"eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
"location": {
"@type": "Place",
"name": "Venue Name",
"address": {
"@type": "PostalAddress",
"streetAddress": "Unter den Linden 1",
"addressLocality": "Berlin",
"postalCode": "10117",
"addressCountry": "DE"
}
},
"offers": {
"@type": "Offer",
"url": "https://tickets.example.com",
"price": "0",
"priceCurrency": "EUR",
"availability": "https://schema.org/InStock"
},
"organizer": {
"@type": "Organization",
"name": "Berlin Tech",
"url": "https://berlintech.example.com"
}
}
LocalBusiness
| Property | Required | Notes |
|---|---|---|
name | ✓ | |
address | ✓ | PostalAddress |
telephone | — | |
url | — | |
openingHoursSpecification | — | Array of OpeningHoursSpecification |
geo | — | GeoCoordinates — min 5 decimal places |
priceRange | — | e.g. "€€" |
servesCuisine | — | For restaurants |
aggregateRating | — | |
menu | — | URL, for food businesses |
json
{
"@context": "https://schema.org/",
"@type": "Restaurant",
"name": "Trattoria Roma",
"address": {
"@type": "PostalAddress",
"streetAddress": "Via Roma 10",
"addressLocality": "Rome",
"postalCode": "00100",
"addressCountry": "IT"
},
"telephone": "+39 06 1234567",
"servesCuisine": "Italian",
"priceRange": "€€",
"geo": {
"@type": "GeoCoordinates",
"latitude": 41.90278,
"longitude": 12.49636
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "12:00",
"closes": "22:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday", "Sunday"],
"opens": "12:00",
"closes": "23:00"
}
]
}
Recipe
| Property | Required | Notes |
|---|---|---|
name | ✓ | |
image | ✓ | |
author | — | |
prepTime | — | ISO 8601 duration |
cookTime | — | ISO 8601 duration |
totalTime | — | ISO 8601 duration |
recipeYield | — | e.g. "4 servings" |
recipeIngredient | — | Array of strings |
recipeInstructions | — | Array of HowToStep |
nutrition | — | NutritionInformation |
aggregateRating | — | |
recipeCategory | — | e.g. "Dessert" |
recipeCuisine | — | e.g. "Italian" |
json
{
"@context": "https://schema.org/",
"@type": "Recipe",
"name": "Pasta Carbonara",
"image": "https://example.com/carbonara.jpg",
"author": { "@type": "Person", "name": "Angelo" },
"prepTime": "PT10M",
"cookTime": "PT20M",
"totalTime": "PT30M",
"recipeYield": "2 servings",
"recipeCategory": "Main course",
"recipeCuisine": "Italian",
"recipeIngredient": [
"200g spaghetti",
"100g guanciale",
"2 eggs",
"50g Pecorino"
],
"recipeInstructions": [
{ "@type": "HowToStep", "text": "Cook pasta in salted boiling water." },
{ "@type": "HowToStep", "text": "Fry guanciale until crispy." },
{
"@type": "HowToStep",
"text": "Mix eggs and cheese, combine with pasta off heat."
}
],
"nutrition": {
"@type": "NutritionInformation",
"calories": "650 calories"
}
}
FAQPage
json
{
"@context": "https://schema.org/",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is schema.org?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Schema.org is a shared vocabulary for structured data on the web, backed by Google, Microsoft, Yahoo, and Yandex."
}
},
{
"@type": "Question",
"name": "How do I validate structured data?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Use the <a href='https://search.google.com/test/rich-results'>Google Rich Results Test</a> or <a href='https://validator.schema.org/'>Schema.org Validator</a>."
}
}
]
}
Answer text supports basic HTML: <a>, <p>, <ul>, <ol>, <li>, <b>, <strong>, <i>, <em>, <br>, <h1>–<h6>.
json
{
"@context": "https://schema.org/",
"@type": "BreadcrumbList",
"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 Article" }
]
}
item is optional on the last element — Google uses the current page URL.
JobPosting
| Property | Required | Notes |
|---|---|---|
title | ✓ | Job title only — no codes or company name |
description | ✓ | Full HTML description |
datePosted | ✓ | ISO 8601 |
hiringOrganization | ✓ | Organization with name |
jobLocation | ✓* | Place — omit for remote, use jobLocationType instead |
validThrough | — | Expiry date |
employmentType | — | FULL_TIME, PART_TIME, CONTRACTOR, TEMPORARY, INTERN, VOLUNTEER, PER_DIEM, OTHER |
baseSalary | — | MonetaryAmount |
jobLocationType | — | "TELECOMMUTE" for fully remote |
directApply | — | Boolean |
json
{
"@context": "https://schema.org/",
"@type": "JobPosting",
"title": "Backend Engineer",
"description": "<p>We are looking for a backend engineer...</p>",
"datePosted": "2024-01-18",
"validThrough": "2024-04-18",
"employmentType": "FULL_TIME",
"hiringOrganization": {
"@type": "Organization",
"name": "Acme Corp",
"sameAs": "https://acme.com",
"logo": "https://acme.com/logo.png"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressLocality": "Berlin",
"addressCountry": "DE"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "EUR",
"value": {
"@type": "QuantitativeValue",
"value": 90000,
"unitText": "YEAR"
}
}
}
VideoObject
| Property | Required | Notes |
|---|---|---|
name | ✓ | |
thumbnailUrl | ✓ | |
uploadDate | ✓ | ISO 8601 |
description | — | |
contentUrl | — | Direct video file URL |
embedUrl | — | Player URL (not the page) |
duration | — | ISO 8601 duration |
expires | — | When it becomes unavailable |
hasPart | — | Clip array for key moments |
interactionStatistic | — | View count |
json
{
"@context": "https://schema.org/",
"@type": "VideoObject",
"name": "How to make pasta",
"description": "Step-by-step tutorial.",
"thumbnailUrl": "https://example.com/thumb.jpg",
"uploadDate": "2024-01-15",
"duration": "PT5M30S",
"embedUrl": "https://example.com/embed/abc123",
"hasPart": [
{
"@type": "Clip",
"name": "Ingredients",
"startOffset": 0,
"endOffset": 60,
"url": "https://example.com/embed/abc123?t=0"
},
{
"@type": "Clip",
"name": "Cooking",
"startOffset": 61,
"endOffset": 330,
"url": "https://example.com/embed/abc123?t=61"
}
]
}
WebSite + Sitelinks Search Box
json
{
"@context": "https://schema.org/",
"@type": "WebSite",
"url": "https://example.com/",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://example.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
ISO 8601 Duration Quick Reference
Used in prepTime, cookTime, duration, etc.:
| Value | Meaning |
|---|---|
PT30M | 30 minutes |
PT1H | 1 hour |
PT1H30M | 1 hour 30 minutes |
P1D | 1 day |
PT5M30S | 5 minutes 30 seconds |
Format: P[n]Y[n]M[n]DT[n]H[n]M[n]S — T separates date from time portion.