Topic 6.6
Structured Data
In one line
Structured data is a JSON-LD block that describes the page's content in schema.org vocabulary (a product with a price, a recipe with a cooking time), so search engines can understand it exactly and may show rich results like stars and prices.
Think of it like this
A form at the doctor's office. You could write your details as a story ("I'm Ravi, I was born in March 1990..."), but the receptionist prefers a form with labelled boxes: Name, Date of birth, Phone. Your web page is the story; structured data is the form, filled in with labelled boxes a machine can read without guessing.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Structured data
- Facts about a page written in a fixed, labelled format that machines can read exactly.
- schema.org
- A shared dictionary of types (Product, Recipe) and properties (price, author) used for structured data.
- JSON-LD
- Structured data written as JSON inside
<script type="application/ld+json">. - @context
- The JSON-LD key that says which vocabulary you are using, usually
https://schema.org. - @type
- The JSON-LD key that says what kind of thing this is, like
ProductorRecipe. - Property
- One labelled fact about a thing, like its
nameorprice. - Rich result
- A search result with extras like stars, prices or cooking times.
- Microdata
- An older way to add structured data with
itempropattributes on normal HTML elements. - Manual action
- A penalty a Google reviewer applies to a site for breaking its rules.
Step by step
01Start with the visible page
Structured data describes what is already on the page. Here the product page shows a name, a picture, a price, stock status and a rating.
<h1>Blue Cotton School Bag</h1>
<p class="price">₹899</p>
<p>In stock</p>
<p>★ 4.6 (128 reviews)</p>02Pick the type
Look it up on schema.org: this is a Product. Google's documentation for product snippets lists which properties are required and recommended.
03Write the JSON-LD
Same facts, in labelled boxes. Prices are plain numbers (or strings of digits) with a separate priceCurrency in ISO 4217 codes (INR, USD); availability uses a schema.org URL.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Blue Cotton School Bag",
"image": "https://bagbazaar.example/img/blue-bag.jpg",
"offers": {
"@type": "Offer",
"price": "899",
"priceCurrency": "INR",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "128"
}
}
</script>04Add breadcrumbs
A BreadcrumbList tells search engines where the page sits in your site, so the result can show BagBazaar › School › Bags instead of a long URL. Positions start at 1.
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "School", "item": "https://bagbazaar.example/school" },
{ "@type": "ListItem", "position": 2, "name": "Bags", "item": "https://bagbazaar.example/school/bags" }
]
}05Test it
Paste the URL or the code into the Rich Results Test. It lists detected items ("Product snippets", "Breadcrumbs"), errors that make an item ineligible, and warnings about missing recommended properties.
Try it yourself
- 1
Change the price
In the first example, change the price to
799in the JSON-LD only. Run it. The rich line now disagrees with the visible page: that mismatch is exactly what Google's guidelines forbid. Fix both. - 2
Out of stock
Change
availabilitytohttps://schema.org/OutOfStock. Predict the fourth console line, then run. - 3
Add a level
In the second example, add a fourth link
Backpackstohttps://bagbazaar.example/school/bags/backpacks. Predict its position number before running.
Code & diagrams
A crawler parses the JSON exactly like this. The grey line under the fake result is what a rich result might add.
Preview
Console
Nothing logged yet.Expected console output
Type: Product
Name: Blue Cotton School Bag
Price: 899 INR
In stock: trueBuilding JSON-LD from the same data as the visible page keeps the two in sync. On a real site, do this on the server or at build time so every crawler sees it.
Preview
Console
Nothing logged yet.Expected console output
1 Home https://bagbazaar.example/
2 School https://bagbazaar.example/school
3 Bags https://bagbazaar.example/school/bags
JSON-LD blocks in the head: 1<div itemscope itemtype="https://schema.org/Product">
<h1 itemprop="name">Blue Cotton School Bag</h1>
<div itemprop="offers" itemscope itemtype="https://schema.org/Offer">
<span itemprop="priceCurrency" content="INR">₹</span><span itemprop="price" content="899">899</span>
<link itemprop="availability" href="https://schema.org/InStock">In stock
</div>
</div>Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Invalid JSON hides everything
In the first example, add a comma after the last property ("reviewCount": "128" }, before the closing }).
Break #2
User text that closes the script tag
On the server, build JSON-LD with JSON.stringify(review) where a user's review text contains </script>.
Myth vs fact
Myth
Structured data improves your ranking.
Fact
Google says it's not a general ranking factor. It helps search engines understand the page and makes it eligible for rich results, which can raise clicks.
Myth
Valid markup guarantees stars in search results.
Fact
Valid markup makes a page eligible. Google decides per search whether to show a rich result, and some types (FAQ, HowTo) are now heavily limited.
Myth
You can mark up things that aren't on the page.
Fact
Markup must describe visible, true content. Hidden or misleading markup breaks the guidelines and can lead to a manual action.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Google supports JSON-LD injected by JavaScript (it renders pages), but other consumers (Bing for some features, social apps, many AI crawlers) may only read the server HTML. Server-render it.
- ▸
Use
@idwith stable URLs (https://example.com/#organization) to connect entities across pages: anArticle'spublishercan point to the site'sOrganizationinstead of repeating it. This builds a consistent entity graph. - ▸
Dates use ISO 8601 (
2026-10-05, durations likePT20Mfor 20 minutes inRecipe.cookTime). Wrong formats are the most common Rich Results Test errors after missing required fields. - ▸
Next.js's documentation recommends exactly the
<→\u003creplacement when rendering JSON-LD withdangerouslySetInnerHTML; Hectal's<JsonLd>component follows the same idea.
Remember this
- 1
Search engines read your text and guess what it means. Structured data removes the guessing: it states facts in a shared vocabulary. That vocabulary is schema.org, a project started in 2011 by Google, Microsoft, Yahoo and Yandex. It defines types (
Product,Recipe,Article,Event,Organization,BreadcrumbList,Course...) and the properties each type can have (name,price,author,startDate...). - 2
The recommended format is JSON-LD (JSON for Linked Data): a
<script type="application/ld+json">block containing JSON. The browser doesn't run it, because its type isn't JavaScript; it's data for machines. It can go in the head or the body."@context": "https://schema.org"says which vocabulary you use,"@type"says what the thing is, and the other keys are its properties. - 3
Properties can hold other typed things: a
Producthasoffers, which is anOfferwithpriceandpriceCurrency, andaggregateRating, anAggregateRatingwithratingValueandreviewCount. This nesting is how you describe real relationships.@idgives a thing a unique URL-like name so other blocks can refer to it, and@graphholds several things in one block. - 4
Rich results are search results with extras: star ratings, prices and stock, recipe cooking times, event dates, breadcrumb trails instead of URLs. Google decides when to show them; valid markup makes a page eligible, not guaranteed. Google's support changes over time: since 2023, FAQ rich results appear only for well-known government and health sites, and HowTo rich results were removed. Check Google's Search Gallery for what is currently supported.
- 5
The golden rule: mark up only what is visible on the page and true. A 5-star rating in JSON-LD that doesn't appear on the page, or a fake price, breaks Google's guidelines and can earn a manual action (a penalty that removes your rich results). The older formats Microdata (
itemscope,itemtype,itempropattributes woven into the HTML) and RDFa still work, but JSON-LD is easier to keep separate from your markup. - 6
Test with Google's Rich Results Test (which features your page qualifies for, and errors) and the Schema Markup Validator at validator.schema.org (checks against the full vocabulary). After launch, Search Console's enhancement reports show errors across the whole site. Hectal itself adds
Courseand breadcrumb JSON-LD to every course and topic page.
Explain it without notes
What is structured data, and why is JSON-LD the recommended format?
What are rich results, and does valid markup guarantee them?
Why must structured data match the visible page?
How do you safely embed user-provided text in a JSON-LD block?
Practice
Write a JSON-LD Recipe for "Egg-free pancakes" by Asha, ready in 20 minutes (cook time 10 minutes), making 8 pancakes, with three ingredients.
Write a function toJsonLd(data) that returns a string safe to put inside a <script type="application/ld+json">. Test it with { name: "</script>hi" } and log whether the result contains </script.
Trade-offs
- ↔
JSON-LD is separate from the visible HTML, which makes it easy to maintain but also easy to let drift out of sync with the page; generating both from the same data solves that.
- ↔
Marking up every possible type costs build time and testing; focus on the types that have rich results for your kind of site (products, recipes, articles, events, breadcrumbs).
Done when you can
I can write a JSON-LD block with
@context,@typeand properties.I can nest types, like an
Offerinside aProduct.I can add a
BreadcrumbList.I mark up only visible, true content.
I can test markup with the Rich Results Test and Schema Markup Validator.
I escape
<when embedding JSON-LD built from user data.