Structured Data and JSON-LD: A Practical Guide for 2026

Structured data is JSON-LD code you add to a page so Google reads facts about your business, articles, or products directly instead of guessing. It makes you eligible for rich results like star ratings and FAQs. It never guarantees them. Google still decides what to show.
Part of the complete SEO guide.
On this page
- What structured data actually does
- The JSON-LD skeleton
- The types worth your time
- A real LocalBusiness example
- Article markup for blog posts
- FAQ markup, used honestly
- Mistakes I see over and over
- How to validate it
- Do you need it?
- FAQ
- Does JSON-LD directly improve my rankings?
- Can I add JSON-LD through a plugin?
- What happens if my structured data has errors?
Structured data is one of those things that sounds more complicated than it is. You’re adding a small block of JSON to a page so search engines can read facts about your business, your articles, or your products without guessing. Done right, it earns you rich results. Done wrong, it does nothing at all, and most sites I audit have it done wrong.
This is the version of the guide I wish existed when I started wiring this stuff up: what the schema actually does in 2026, which types matter, and copy-paste examples you can adapt today.
What structured data actually does
Search engines read your HTML and infer meaning from it. Structured data removes the inference. Instead of hoping Google figures out that “Mon–Fri 8–5” is your opening hours, you state it explicitly in a machine-readable format.
Google then uses those facts to build rich results: star ratings, FAQ dropdowns, business hours, breadcrumbs, event dates. It doesn’t guarantee anything. Google decides what to show based on its own judgment and the query. But you can’t be considered for a rich result you never declared.
The format Google recommends is JSON-LD. It’s a script tag containing JSON, separate from your visible markup. That’s why I prefer it: you can add, change, or remove it without touching your layout, and it doesn’t break when you redesign.
The JSON-LD skeleton
Every block lives inside a script tag with a specific type. Here’s the minimum shape:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Your Business Name",
"url": "https://example.com"
}
</script>
Two keys do the heavy lifting. @context tells the parser which vocabulary you’re using, and @type says what kind of thing you’re describing. Everything else is properties of that thing.
The types worth your time
There are hundreds of schema types. You need maybe five. These are the ones that actually produce visible results:
- LocalBusiness (and its subtypes like
Restaurant,Dentist,HomeAndConstructionBusiness) for any business with a physical location or service area. - Article or BlogPosting for editorial content.
- BreadcrumbList for site hierarchy. Low effort, shows up often.
- FAQPage for genuine question-and-answer content. Google has tightened eligibility here, so only use it when the questions and answers are actually on the page.
- Product with
OfferandAggregateRatingif you sell things.
Everything else is usually noise unless you’re in a niche that specifically supports it (recipes, events, job postings, courses).
A real LocalBusiness example
Here’s a filled-out version for a service business. Notice that every value here is something a human could verify by looking at the page.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProfessionalService",
"name": "Example Plumbing Co",
"url": "https://example.com",
"telephone": "+1-631-555-0142",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "12 Main St",
"addressLocality": "Commack",
"addressRegion": "NY",
"postalCode": "11725",
"addressCountry": "US"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 40.8429,
"longitude": -73.2926
},
"areaServed": [
{ "@type": "City", "name": "Commack" },
{ "@type": "City", "name": "Smithtown" }
],
"openingHoursSpecification": [
{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "08:00",
"closes": "17:00"
}
]
}
</script>
If you serve a region rather than a storefront, areaServed matters more than geo. Don’t invent coordinates you can’t stand behind.
Article markup for blog posts
For a blog post, keep it tight. Google wants the headline, the author, the dates, and the image.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Structured Data and JSON-LD: A Practical Guide",
"datePublished": "2026-01-14",
"dateModified": "2026-01-14",
"author": {
"@type": "Person",
"name": "Ken Key",
"url": "https://www.kennykey.com/about/"
},
"publisher": {
"@type": "Organization",
"name": "Kenny Key",
"logo": {
"@type": "ImageObject",
"url": "https://www.kennykey.com/logo.png"
}
},
"mainEntityOfPage": "https://www.kennykey.com/blog/structured-data-json-ld/"
}
</script>
One thing people get wrong constantly: dateModified should change when you actually change the content, not every time you touch a template. Faking freshness is the kind of thing that erodes trust over time.
FAQ markup, used honestly
FAQ rich results have gotten more restricted. The rule that matters: the questions and answers in your JSON-LD must match content visible on the page. If you hide them or stuff them only in the script, you’re asking for a manual action.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Does structured data improve rankings?",
"acceptedAnswer": {
"@type": "Answer",
"text": "It doesn't directly boost rankings, but it can earn rich results that increase click-through rate."
}
}
]
}
</script>
Mistakes I see over and over
- Marking up things that aren’t on the page. If your JSON says you have 400 reviews and the page shows none, that’s a problem.
- Fake reviews and ratings. Google’s spam policies are explicit about self-serving review markup. Don’t.
- Broken JSON. One trailing comma kills the whole block silently. Validate it.
- Duplicating the same entity on every page. Your LocalBusiness block belongs on your contact or homepage, not stapled to all 200 URLs.
- Treating it as a ranking hack. It’s a clarity tool. That’s it.
If you’re maintaining a site with a CMS, the cleanest approach is to template the JSON-LD so it pulls from the same fields that render the visible page. That way the two can’t drift apart. This is the kind of thing that falls out naturally when you build with custom web development rather than bolting plugins onto a theme and hoping.
How to validate it
Two tools, both free, both worth using before you ship anything:
- Schema Markup Validator (validator.schema.org) checks the syntax and vocabulary.
- Google Rich Results Test checks what Google can actually extract and whether it qualifies for a rich result.
Run the URL, not just the pasted snippet, so you catch conflicts between multiple blocks on the same page. Then check Search Console’s Enhancements reports a week or two later to see what Google indexed.
Do you need it?
If you have a business site, a blog, or anything with products or events, yes. It’s low effort and the upside is real. If you have a five-page brochure site with no local component and no articles, it’s not a priority compared to making the pages load fast and read well.
Start with one type. Get it validated. Then add the next. Structured data rewards patience and honesty, and punishes everything else.
FAQ
Does JSON-LD directly improve my rankings?
No. It doesn’t move rankings on its own. It can earn rich results, which take up more space in search and tend to get more clicks, and better click-through can indirectly help over time.
Can I add JSON-LD through a plugin?
Yes, and for simple sites it’s fine. The catch is that plugins often output generic or duplicate markup you don’t control. If you want it precise, templating it into your own code is cleaner.
What happens if my structured data has errors?
Usually nothing visible. Google ignores invalid blocks silently, so you lose the rich result without any warning. That’s why validating before you ship matters more than most people assume.


