Structured Data and JSON-LD
Machine readable facts about your page, using a shared vocabulary. It does not raise rankings, and it can change how your result looks entirely.
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
Concept
Structured data states facts about a page in a form machines read directly: this is an article, published on this date, by this author. A crawler can infer some of that from the markup. Structured data removes the guessing.
The vocabulary is Schema.org, shared across search engines. The recommended format is JSON-LD - a script block in the head, separate from the visible markup.
It does not improve rankings. What it does is make a page eligible for rich results: star ratings, event dates, recipe times, breadcrumb trails, FAQ accordions in the result itself. Those change how much of the page a searcher sees before clicking, which changes how many click.
Syntax
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "How to read a bus timetable",
"datePublished": "2026-03-02",
"dateModified": "2026-08-11",
"author": {
"@type": "Person",
"name": "Meera Iyer"
},
"publisher": {
"@type": "Organization",
"name": "Riverside Journal",
"logo": {
"@type": "ImageObject",
"url": "https://example.edu/logo.png"
}
},
"image": "https://example.edu/images/bus-stop.jpg",
"mainEntityOfPage": "https://example.edu/journal/bus-timetable"
}
</script>The script has a specific type attribute, so browsers never execute or display it. Three keys are structural: @context names the vocabulary, @type names the thing, and the rest are its properties.
The types worth knowing
BreadcrumbList
Shows the site hierarchy in the result instead of a bare URL. Straightforward to add and applicable to most sites.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.edu/" },
{ "@type": "ListItem", "position": 2, "name": "Courses", "item": "https://example.edu/courses" },
{ "@type": "ListItem", "position": 3, "name": "Design", "item": "https://example.edu/courses/design" }
]
}
</script>FAQPage
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "When do applications close?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Applications close on 30 June at five in the afternoon."
}
},
{
"@type": "Question",
"name": "What documents do I need?",
"acceptedAnswer": {
"@type": "Answer",
"text": "A photocopy of your identity card, two photographs and the original receipt."
}
}
]
}
</script>Every question and answer must be visible on the page. Marking up content that is not there is a violation and the markup will be ignored or penalised.
Organization and LocalBusiness
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "CollegeOrUniversity",
"name": "Riverside College",
"url": "https://example.edu",
"logo": "https://example.edu/logo.png",
"telephone": "+91-20-2600-1234",
"address": {
"@type": "PostalAddress",
"streetAddress": "14 Sadar Bazaar Road",
"addressLocality": "Pune",
"postalCode": "411001",
"addressCountry": "IN"
},
"sameAs": [
"https://www.linkedin.com/company/example",
"https://en.wikipedia.org/wiki/Example"
]
}
</script>sameAs links the organisation to its profiles elsewhere, which helps a search engine connect them as one entity.
Product
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Two litre electric kettle",
"image": "https://example.com/images/kettle.jpg",
"description": "Boils in ninety seconds. Two year warranty.",
"sku": "KET-2L-001",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/kettle",
"priceCurrency": "INR",
"price": "2499",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.4",
"reviewCount": "87"
}
}
</script>Others in common use
| Type | For |
|---|---|
Article, NewsArticle, BlogPosting | Written content |
Event | Dates, venues, tickets |
Recipe | Ingredients, times, nutrition |
Course | Educational offerings |
JobPosting | Vacancies |
VideoObject | Video content |
HowTo | Step by step instructions |
WebSite | Enables a site search box in results |
Combining several on one page
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{ "@type": "BreadcrumbList", "itemListElement": [ ... ] },
{ "@type": "Article", "headline": "...", "author": { "@id": "#author" } },
{ "@type": "Person", "@id": "#author", "name": "Meera Iyer" }
]
}
</script>@graph holds several objects in one block, and @id lets them reference each other rather than repeating the same author details three times.
The rules Google enforces
- Mark up only what is visible on the page. Invisible or contradictory structured data is a violation.
- Be accurate. Fabricated ratings or prices lead to a manual penalty.
- Include the required properties for each type; without them the page is not eligible for the rich result.
- Rich results are never guaranteed. Valid markup makes a page eligible, not entitled.
- Render it server side. Injecting it with JavaScript can work but delays or prevents recognition.
Testing
- The Rich Results Test - paste a URL or the markup and see which rich results the page qualifies for.
- The Schema Markup Validator - checks the syntax against Schema.org itself, beyond what Google supports.
- Search Console Enhancements - reports valid and invalid structured data across the whole site over time.
Test before shipping. A missing required property is silent - nothing breaks, the rich result simply never appears.
Microdata and RDFa
<!-- microdata: attributes woven into the markup -->
<article itemscope itemtype="https://schema.org/Article">
<h1 itemprop="headline">How to read a bus timetable</h1>
<span itemprop="author">Meera Iyer</span>
</article>Both are still supported, and both entangle the data with the markup so that a design change can break it. JSON-LD sits in one block, is easy to generate from a template, and is what Google recommends. Use it.
Important rules
- Structured data affects appearance, not ranking.
- Only mark up visible content.
- Each type has required properties.
- JSON-LD in a
application/ld+jsonscript block is the recommended form. - Server render it.
- Test before shipping.
Common mistakes
- Marking up content that is not on the page.
- Invented ratings and review counts.
- Missing required properties, so nothing appears.
- Invalid JSON - a trailing comma silently breaks the whole block.
- Relative URLs where absolute ones are required.
- Structured data contradicting the visible page.
- Adding it to every page indiscriminately rather than where a rich result exists.
Best practices
- Start with
BreadcrumbListandOrganization; both apply almost everywhere. - Add the type that matches what the page actually is.
- Generate it from the same data that renders the page, so the two cannot diverge.
- Use
@graphfor several objects rather than several script blocks. - Validate with the Rich Results Test on every template.
- Watch the Enhancements report for regressions.
Practice
- Add
BreadcrumbListto a deep page and test it with the Rich Results Test. - Mark up a real FAQ section where every question is visible on the page.
- Add
Articlemarkup generated from the same data that renders the byline and date. - Remove one required property and observe what the test reports.