Structured Data
Schema.org and JSON-LD: complete guide to Organization, Product, ratings and photos

Complete Schema.org structured data guide: JSON-LD vs Microdata formats, schema priority for [rich results](/glossary/rich-results), Organization and all subtypes, Product with Offer and AggregateOffer, ratings, reviews and photos — with working code.
Schema.org structured data is a vocabulary that search engines use to understand page content. Implemented correctly, it turns an ordinary snippet into a rich result — with star ratings, product prices, business hours or photos displayed directly in Google's search results.
This article covers the complete system: from choosing the right format and prioritising schemas to concrete JSON-LD code for Organization, Product, AggregateRating, Review and ImageObject — with special attention to the subtypes most often overlooked.
<script> → Google parses the structure → rich snippet with rating stars and price right in the SERP.What is Schema.org and why use structured data
Schema.org is a joint project of Google, Bing, Yahoo and Yandex launched in 2011. The vocabulary contains over 900 data types and thousands of properties. All types inherit from the base Thing and branch into Person, Organization, Product, Event, CreativeWork, Action and others.
CTR lift from rich results
Snippets with star ratings and other rich elements consistently show higher CTR compared to plain snippets
Types in Schema.org
The vocabulary covers everything from recipes and products to scientific papers and software
Google's recommendation
Google officially recommends JSON-LD for all new structured data implementations
Direct ranking impact
Markup does not directly boost rankings, but rich results raise CTR — which indirectly improves ranking signals
Schema.org markup solves three problems at once. For search engines — it unambiguously identifies entities: this is an organisation, not just text with a company name; this is a product price, not just a number. For users — rich results in the SERP make snippets more informative before the click. For the business — higher CTR and presence in the Knowledge Graph.
Formats: JSON-LD, Microdata, RDFa
Schema.org structured data can be added in three ways. For new projects the choice is clear — JSON-LD. The others are supported but harder to maintain.
| Format | Where it lives | HTML coupling | Google recommendation |
|---|---|---|---|
| JSON-LD | <script type="application/ld+json"> tag | Separate from HTML | Preferred |
| Microdata | itemscope, itemtype, itemprop attributes | Embedded in HTML elements | Supported |
| RDFa | vocab, typeof, property attributes | Embedded in HTML elements | Supported |
The base JSON-LD template is the same for any page: a <script> tag with type application/ld+json, containing a JSON object with the mandatory @context and @type fields. The tag can go in <head> or at the end of <body>. Multiple schemas — multiple separate <script> blocks.
<!-- Base JSON-LD template -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Site Name",
"url": "https://example.com"
}
</script>
<!-- Multiple schemas — multiple <script> blocks -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Company",
"url": "https://example.com"
}
</script>Schema priority: what gives rich results in Google
Not every Schema.org type produces a rich result. Google supports a limited set of types that give visual enhancements in the SERP. Other schemas help Google understand content but do not change the appearance of the snippet.
Business and organisations
LocalBusiness, Restaurant, Store — business hours, address, phone, ratings in the Knowledge Panel. Top priority for local businesses.
Products and prices
Product + Offer — price, availability, ratings directly in the snippet. Google Shopping and rich snippets. Essential for e-commerce.
Content and FAQ
Article, FAQPage, HowTo — FAQ expands directly in search results, giving much more SERP real estate for your page.
Ratings and reviews
AggregateRating + Review — star ratings in the snippet. The most visually prominent element. Works for Product, LocalBusiness, Recipe, Course.
| Schema type | Rich result in Google | Priority |
|---|---|---|
| Product + Offer | Price, availability, ratings in snippet; Shopping cards | Critical for e-commerce |
| LocalBusiness + AggregateRating | Knowledge Panel, Map Pack, stars | Critical for local business |
| FAQPage | Expandable questions beneath the snippet | High for content pages |
| Article / NewsArticle | Top Stories carousel, publication date | High for media and blogs |
| BreadcrumbList | Breadcrumbs instead of URL in snippet | High for any site |
| HowTo | Step-by-step instructions with photos in SERP | Medium for tutorial pages |
| Event | Event card with date and location | Medium for event pages |
| Recipe | Recipe card with photo, time, calories | Medium for cooking sites |
| Organization (non-Local) | Knowledge Graph, logo in results | Baseline for all sites |
Organization — base schema and all subtypes
Organization is the base type for any company, organisation or brand. The subtype hierarchy is broad — each subtype adds specific fields. Choosing the right subtype matters: Google uses it to determine the business context and what to display in the Knowledge Panel.
| Type | For whom | Key additional fields |
|---|---|---|
| Organization | Any company, NGO, brand without a physical address | name, url, logo, sameAs |
| LocalBusiness | Any business with a physical address | address, telephone, openingHours, geo |
| Store | Retail store | currenciesAccepted, paymentAccepted |
| FoodEstablishment | Cafe, restaurant (base type) | servesCuisine, menu, hasMap |
| Restaurant | Restaurant | servesCuisine, menu, acceptsReservations |
| CafeOrCoffeeShop | Coffee shop | servesCuisine |
| FastFoodRestaurant | Fast food | servesCuisine |
| MedicalOrganization | Medical institution (base) | medicalSpecialty |
| Hospital | Hospital | availableService, medicalSpecialty |
| MedicalClinic | Clinic | medicalSpecialty, availableService |
| Dentist | Dental practice | availableService |
| LegalService | Law firm | — |
| Lawyer | Attorney / lawyer | — |
| AccountingService | Accounting / audit firm | — |
| FinancialService | Bank, insurer, investment firm | — |
| RealEstateAgent | Real estate agency | — |
| AutomotiveBusiness | Car dealer, auto repair (base) | — |
| AutoDealer | Car dealership | — |
| AutoRepair | Auto repair shop | — |
| Hotel | Hotel | amenityFeature, checkinTime, checkoutTime |
| SportsActivityLocation | Sports venue (base) | availableService |
| GymOrHealthClub | Gym / fitness club | — |
| GovernmentOrganization | Government organisation | — |
| EducationalOrganization | Educational institution (base) | — |
| CollegeOrUniversity | University / college | — |
| School | School | — |
| Corporation | Large corporation | tickerSymbol, legalName |
Base Organization
The base Organization schema is added to the homepage of any site. It helps Google identify the brand and link it to external profiles via sameAs. The @id field with a unique identifier lets other schemas reference this organisation without duplicating data.
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Company Name",
"legalName": "Example LLC",
"url": "https://example.com",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png",
"width": 200,
"height": 60
},
"description": "Brief company description for Knowledge Graph.",
"foundingDate": "2015",
"contactPoint": {
"@type": "ContactPoint",
"telephone": "+1-800-123-4567",
"contactType": "customer service",
"availableLanguage": "English"
},
"sameAs": [
"https://www.linkedin.com/company/yourcompany",
"https://twitter.com/yourcompany",
"https://www.facebook.com/yourcompany"
]
}LocalBusiness — physical business with an address
LocalBusiness is the most important subtype for businesses with a physical location. A correctly filled schema improves chances of appearing in the Google Map Pack (the map block at the top of the SERP) and a Knowledge Panel with business hours. Key fields: address, geo, openingHoursSpecification, telephone, priceRange.
{
"@context": "https://schema.org",
"@type": "Restaurant",
"@id": "https://example.com/#business",
"name": "The Birch Restaurant",
"url": "https://example.com",
"telephone": "+1-212-555-0100",
"email": "info@example.com",
"servesCuisine": ["American", "European"],
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "123 Main Street",
"addressLocality": "New York",
"addressRegion": "NY",
"postalCode": "10001",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 40.7128,
"longitude": -74.0060
},
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"opens": "12:00",
"closes": "23:00"
},
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Saturday", "Sunday"],
"opens": "12:00",
"closes": "00:00"
}
],
"image": "https://example.com/photos/restaurant.jpg",
"hasMap": "https://maps.google.com/?cid=XXXXXX"
}sameAs — linking to external profiles
The sameAs field tells Google that your organisation is identical to profiles on external platforms. This is the key field for building the Knowledge Graph — Google's entity database. The more authoritative sources confirm an organisation's existence, the higher the probability of appearing in a Knowledge Panel.
- Wikidata (most authoritative): https://www.wikidata.org/wiki/Q...
- Wikipedia: https://en.wikipedia.org/wiki/...
- LinkedIn, Twitter/X, Facebook, Instagram
- The organisation's YouTube channel
- Google Business Profile (for local businesses)
- Industry directories — medical registries, bar associations, etc.
Product — product schema and all subtypes
Product is the base schema for any product or item. It works together with Offer (price and availability) and AggregateRating (rating). A correctly implemented Product schema gives a rich result in Google: price, availability status and star ratings right in the snippet.
| Type | Use case | Notes |
|---|---|---|
| Product | Base schema for any product | name, image, description required |
| Offer | Specific listing: price + availability | price, priceCurrency, availability required |
| AggregateOffer | Price range (multiple offers) | lowPrice, highPrice, offerCount |
| ProductGroup | Group of products with variants | variesBy, hasVariant |
| IndividualProduct | Specific variant within a ProductGroup | isVariantOf → ProductGroup |
| Brand | Product brand (nested in Product) | name required |
Base Product with Offer
Google requires a minimum set of fields for a rich result: name, image, description, and a nested Offer with priceCurrency, price and availability. Without at least one of these, the product snippet will not be enriched.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Air X Pro Running Shoes",
"description": "Lightweight running shoes with foam sole for road running. Weight 230g, drop 10mm.",
"sku": "AIRX-001-BLK",
"mpn": "AIRX001",
"gtin13": "0123456789012",
"brand": {
"@type": "Brand",
"name": "RunMax"
},
"image": [
"https://example.com/photos/airx-front.jpg",
"https://example.com/photos/airx-side.jpg",
"https://example.com/photos/airx-back.jpg"
],
"offers": {
"@type": "Offer",
"url": "https://example.com/products/air-x-pro",
"priceCurrency": "USD",
"price": "89.99",
"priceValidUntil": "2026-12-31",
"itemCondition": "https://schema.org/NewCondition",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "Organization",
"name": "RunMax Store"
}
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "128"
}
}AggregateOffer — price range
If a product is offered by multiple sellers or comes in variants with different prices, use AggregateOffer. It shows a price range (lowPrice – highPrice) instead of a single price.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Galaxy S25 Smartphone",
"brand": { "@type": "Brand", "name": "Samsung" },
"image": "https://example.com/galaxy-s25.jpg",
"offers": {
"@type": "AggregateOffer",
"priceCurrency": "USD",
"lowPrice": "799",
"highPrice": "1099",
"offerCount": "3",
"offers": [
{
"@type": "Offer",
"name": "128 GB / Black",
"price": "799",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
{
"@type": "Offer",
"name": "256 GB / White",
"price": "899",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
{
"@type": "Offer",
"name": "512 GB / Violet",
"price": "1099",
"priceCurrency": "USD",
"availability": "https://schema.org/PreOrder"
}
]
}
}ProductGroup — products with variants
ProductGroup is a group of related products that differ by parameters (size, colour, material). Used on product pages with variants. Each specific variant is a nested Product with isVariantOf pointing to the parent ProductGroup.
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"name": "Air X Pro Running Shoes",
"description": "Road running shoes available in multiple colours and sizes.",
"url": "https://example.com/products/air-x-pro",
"brand": { "@type": "Brand", "name": "RunMax" },
"productGroupID": "AIRX-PRO",
"variesBy": ["https://schema.org/color", "https://schema.org/size"],
"hasVariant": [
{
"@type": "Product",
"name": "Air X Pro — Black, US 9",
"sku": "AIRX-BLK-9",
"color": "Black",
"size": "US 9",
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
},
{
"@type": "Product",
"name": "Air X Pro — Blue, US 11",
"sku": "AIRX-BLU-11",
"color": "Blue",
"size": "US 11",
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/OutOfStock"
}
}
]
}AggregateRating and Review — ratings and reviews
Star ratings in search results are the most visually prominent snippet element. They are implemented via two related types: AggregateRating (the combined score from all ratings) and Review (an individual text review). Both types always nest inside a parent schema: Product, LocalBusiness, Recipe, Course, Book, etc.
AggregateRating — combined score
AggregateRating reflects the aggregate score: average value and number of votes. Google renders it as stars in the snippet. Required fields: ratingValue (average) and reviewCount or ratingCount.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Air X Pro Running Shoes",
"image": "https://example.com/airx.jpg",
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"bestRating": "5",
"worstRating": "1",
"reviewCount": "128",
"ratingCount": "215"
}
}Review — individual reviews
Review is the schema for an individual text review. It nests inside the parent object via the review property. Each Review contains an author, rating and body text. Google may display a snippet of the review text in the rich result.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Air X Pro Running Shoes",
"image": "https://example.com/airx.jpg",
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "128"
},
"review": [
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5"
},
"name": "Great shoes for daily runs",
"reviewBody": "Been running in them for 3 months — sole holds up well, feet don't tire. Recommend for road running.",
"datePublished": "2026-03-15",
"author": {
"@type": "Person",
"name": "Alex K."
}
},
{
"@type": "Review",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4",
"bestRating": "5"
},
"reviewBody": "Good cushioning, but runs a little small. Order half a size up.",
"datePublished": "2026-04-01",
"author": {
"@type": "Person",
"name": "Maria S."
}
}
]
}ImageObject — photos in structured data
Images in Schema.org can be specified in two ways: as a URL string ("image": "https://example.com/photo.jpg") or as an ImageObject with metadata. A string is sufficient for most schemas, but for Article, Recipe and HowTo Google recommends ImageObject — it lets you specify dimensions, caption and format.
| Schema type | Image requirements | Min. width |
|---|---|---|
| Product | At least one product image; white background preferred | 800 px recommended |
| Article / NewsArticle | At least 3 images: 16:9, 4:3, 1:1 | 1200 px |
| Recipe | Image of finished dish is required | Any; 1200×628 optimal |
| LocalBusiness | Photos of entrance, interior, facade | Any |
| Organization (logo) | Rectangular, white/transparent background | 112×112 min, up to 1×10 ratio |
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Air X Pro Running Shoes",
"image": [
{
"@type": "ImageObject",
"url": "https://example.com/airx-front.jpg",
"width": 1200,
"height": 1200,
"caption": "Air X Pro — front view"
},
{
"@type": "ImageObject",
"url": "https://example.com/airx-side.jpg",
"width": 1200,
"height": 1200,
"caption": "Air X Pro — side view"
}
],
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
}Combining schemas on one page
Multiple schemas on a single page are added as separate <script> blocks. Here is a complete product page markup: the selling organisation, breadcrumbs, product with price, rating and review.
<!-- Schema 1: Selling organisation (on all site pages) -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "RunMax Store",
"url": "https://example.com",
"logo": "https://example.com/logo.png"
}
</script>
<!-- Schema 2: Breadcrumbs -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com" },
{ "@type": "ListItem", "position": 2, "name": "Footwear", "item": "https://example.com/shoes" },
{ "@type": "ListItem", "position": 3, "name": "Air X Pro" }
]
}
</script>
<!-- Schema 3: Product with price, rating and review (on product page) -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Air X Pro Running Shoes",
"description": "Road running shoes.",
"sku": "AIRX-001",
"brand": { "@type": "Brand", "name": "RunMax" },
"image": "https://example.com/airx.jpg",
"offers": {
"@type": "Offer",
"price": "89.99",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"priceValidUntil": "2026-12-31",
"seller": { "@id": "https://example.com/#organization" }
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "128",
"bestRating": "5"
},
"review": {
"@type": "Review",
"reviewRating": { "@type": "Rating", "ratingValue": "5" },
"author": { "@type": "Person", "name": "Alex K." },
"reviewBody": "Excellent shoes, run in them every day.",
"datePublished": "2026-04-10"
}
}
</script>Validating structured data
After implementation, always validate the markup. Google provides two official tools, and Search Console gives the real picture of what the crawler sees on indexed pages.
Open search.google.com/test/rich-results, enter a URL or HTML. The tool shows which rich results are available for the schema, which fields are required, and what is filled in incorrectly. This is the only place to confirm whether the markup will actually produce visual enhancements in the SERP.
Open validator.schema.org for full validation against the Schema.org standard (not just types Google supports). It checks required properties for each type and warns about incompatible combinations — useful for complex nested schemas.
Search Console → Enhancements → select the schema type. This section shows real errors on indexed pages. Errors here are what is actually blocking rich results right now, on live URLs — the most actionable signal.
Structured data checklist
JSON-LD base implementation
- <script type="application/ld+json"> tag added in <head> or end of <body>
- Every block contains @context: "https://schema.org" and @type
- All main entities have a unique @id in URL-with-fragment format (#name)
- JSON is valid — no trailing commas, all quotes closed
- Markup is present in the server HTML response (not only via JavaScript)
Organization / LocalBusiness
- Correct subtype chosen (Restaurant, Dentist, AutoDealer, etc.) instead of plain Organization
- Filled: name, url, telephone, address (for LocalBusiness)
- geo added with precise coordinates (latitude, longitude)
- openingHoursSpecification filled with English day names and HH:MM times
- sameAs links to at least social profiles + Wikidata (if available)
Product
- Filled: name, description, image (at least one image)
- Nested Offer with: price, priceCurrency, availability, priceValidUntil
- availability uses full URL: https://schema.org/InStock
- sku and/or gtin13 provided for Google Shopping
- AggregateRating nested if the page has user ratings
Ratings and reviews
- AggregateRating contains ratingValue, reviewCount, bestRating, worstRating
- AggregateRating values match real data from the site
- Review is nested inside the parent object (Product / LocalBusiness), not standalone
- Each Review has author (Person), reviewRating, datePublished, reviewBody
- Reviews in markup are real reviews from real users