gora.
note · May 16, 2026 · 11 min read

JSON-LD Schema.org: Which Types to Choose

A case from one of my projects. A landing page with five questions in the FAQ section at the bottom. It had been sitting in Google for a year and a half, impressions were rolling in, CTR around 1.8% — standard for a commercial query in fifth position.

I added FAQPage schema. Just wrapped those same five questions and answers into a JSON-LD block and dropped it into <head>. I didn't touch the page text, not a single letter.

Three weeks later, Google started showing an accordion with those questions in the SERP right under the snippet. Expandable plus signs, answers visible without a click. First on just one query, then three, then seven. CTR over the month went from 1.8% to 3.9%. Position didn't change at all — still fifth. The snippet simply started taking up three times more space in the results.

That's what rich results are. Google renders your page in the SERP differently than your neighbors — review stars, a card with steps, a question accordion, breadcrumbs instead of a long URL. And all you need is to properly mark up your content via schema.org so Google understands what's on your page and agrees to display it in a special way.

Schema.org isn't directly about ranking. It's about how you get displayed once you're already in the results. And about Google actually understanding what's on your page — not guessing, but knowing for sure.


What Schema.org and JSON-LD Are

Schema.org is a shared vocabulary of types and properties for semantic markup of the web. It was created in 2011 jointly by Google, Microsoft, Yahoo, and Yandex. It now contains around 800 types: Person, Organization, Article, Product, Event, Recipe, Movie, MusicAlbum, MedicalCondition — for every meaningful entity that can appear on a page, there's a dedicated type with its own set of properties.

There are three markup formats: Microdata, RDFa, and JSON-LD. Microdata and RDFa get embedded into HTML tags through attributes like itemprop, itemscope, property — meaning they mark up the content in place. JSON-LD is a standalone <script type="application/ld+json"> block that doesn't mix with HTML. Just pure JSON describing the page in parallel.

Google officially recommends JSON-LD. Three reasons. First: easy to maintain — the markup isn't tied to the HTML structure, you can change the layout without breaking schema. Second: it can be generated programmatically — in Next.js or any other framework, you inject it via the metadata API or dangerouslySetInnerHTML. Third: easy to validate — Google's Rich Results Test reads JSON-LD blocks specifically.

Without schema, Google will still figure out what's on your page. It can read regular HTML, it sees the H1, it sees prices, it sees dates. But it's guessing. With schema, it isn't guessing — it knows for sure. This is a Product block with price: 1990, availability: InStock, brand: Apple. No ambiguity.

And most importantly — only with proper schema does Google have the right to display rich results: review stars under the result, an FAQ accordion, a HowTo card, breadcrumbs in the SERP, video previews. Without markup, none of that will appear even on a perfect page.


Which Types to Give Each Page

Website — on the homepage. One sitewide block describing the site itself: name, URL, optionally SearchAction — if you have your own on-site search, Google can pull it straight into the SERP as a "search box". This block goes once on the homepage and isn't duplicated on other pages.

Organization — sitewide, on every page. Company name, logo (image URL, at least 112×112 pixels), contact details, sameAs — an array of links to your social profiles (Twitter, LinkedIn, Facebook, Wikipedia, Crunchbase). This is the foundational signal for the Knowledge Panel — that card on the right in the SERP that shows up for brand queries. Without Organization, Google doesn't understand that several of your domains and accounts belong to the same entity.

BreadcrumbList — on every page deeper than the first level. Describes the path from the homepage to the current page: Home → Blog → Category → This Article. Google renders this path in the SERP instead of a long URL — it looks cleaner, takes up more space, stands out among neighbors. The simplest schema type and one of the most visible improvements in search results. Should be on EVERYTHING that isn't the homepage.

BlogPosting — for blog articles. Fields: headline (title), author (with Person type and a link to the author's profile), datePublished, dateModified, image (cover URL), wordCount, articleSection, keywords. Optionally speakable — indicates which chunks of the article a voice assistant can read aloud. Without BlogPosting, Google understands it's an article, but doesn't know who the author is or when it was updated — and those are E-E-A-T signals.

Article / NewsArticle — for general articles and news. Article is the parent type; BlogPosting and NewsArticle inherit from it. NewsArticle is used for news publications — it's a signal for Google News. If you're not registered with Google News, you should typically use BlogPosting or Article and not force NewsArticle.

FAQPage — for pages with questions and answers. Inside the block — an array of Question, each with acceptedAnswer of type Answer. Google renders this as an expandable accordion in the SERP. It only works if the questions genuinely resemble user questions — "What is X?", "How much does Y cost?", "How do I do Z?". Marketing fluff like "Why are we the best?" will get ignored by Google.

HowTo — for step-by-step guides. Inside — an array of HowToStep, each with text, image, optionally name and url. Plus totalTime, tool, supply (tools and materials). Google renders a card with steps and images right in the SERP. It only works on genuinely step-by-step instructions — "How to replace a battery", "How to set up a router". Not for "10 tips" style articles — there's no sequence of steps there.

Product — for products. price, priceCurrency, availability (InStock / OutOfStock / PreOrder), brand, sku, gtin, condition. Inside — aggregateRating (average rating and review count) and review (individual reviews). Google shows stars, price, and availability right in the SERP. For e-commerce this is a must-have — without Product schema, product pages look much worse in search results than competitors.

Event — for events. startDate, endDate, location (with Place type and address), performer, organizer, offers (tickets with price). EventStatus — EventScheduled / EventPostponed / EventCancelled / EventMovedOnline. Google renders an event card in the SERP and in Google Events, showing the date, location, and a buy-ticket button.

VideoObject — for videos. name, description, thumbnailUrl, uploadDate, duration, contentUrl or embedUrl. Google shows a video preview in the SERP with the duration. It works even if the video isn't hosted on YouTube — your own CDN, Vimeo, anywhere. Without VideoObject, Google may not realize there's a video on the page at all.

WebApplication / SoftwareApplication — for online tools and applications. applicationCategory, operatingSystem, offers (price or freemium), featureList, aggregateRating. Google understands you don't have an article but a tool — and shows the corresponding signals. I use it for all my SaaS pages with interactive checkers.

Person — for author pages and about pages. name, image, jobTitle, worksFor, sameAs (links to the author's profiles on social media, LinkedIn, Twitter). This is an E-E-A-T signal: Google knows who the author is, where they work, where else they can be found. Link Person to author in BlogPosting and you get a connected author-articles graph.

Review / AggregateRating — reviews. Review is a single review with reviewBody, ratingValue, author, and datePublished. AggregateRating is an aggregated score with ratingValue and reviewCount. Google shows stars under the result in the SERP. It works for products, services, recipes, books, films. It doesn't work as a "site-wide average" — you need to attach it to a specific page with specific content being rated.



Common Mistakes

Schema doesn't match the visible content. The most dangerous mistake. You marked up a FAQPage with five questions, but those questions are hidden on the page, or aren't there at all, or are written with different text. Google picks up on this. If the mismatch is systematic, you get hit with a manual action: "Structured data doesn't match content." Snippets get turned off across the whole domain. Recovery takes months. The rule is simple: in your schema, exactly what the user sees on the page. No more, no less.

Duplicates with different @ids. Two Organization blocks on one page with different @ids. One from header.tsx, the second from layout.tsx, you forgot to remove the old one. Google sees that the site supposedly has two different organizations, gets confused, and may ignore both. Check with Rich Results Test — it shows all the blocks it found. There should be one Organization, one Website, one Article — one of each type.

Broken JSON. An extra comma after the last field, an unclosed bracket, the wrong kind of quotes. The whole JSON breaks, not just part of it — Google parses nothing from the block. It's especially fun when you inject JSON-LD via a template with variables — one unescaped quote in the article title and the block is dead. Always validate via https://search.google.com/test/rich-results after edits.

FAQPage with marketing-style "questions". "Why choose us?", "What are the benefits?", "What sets us apart?" — Google sees this and doesn't show it. The algorithm is specifically trained to filter out marketing. FAQPage works when questions resemble what users actually type into search: "How much does installation cost?", "How long does shipping take?", "Can I return the item?". Informational, specific, focused on one topic.

HowTo not on a step-by-step guide. Google renders HowTo as a card with steps — therefore it requires the steps to actually be sequential and independent. "10 SEO tips" isn't a HowTo, it's a list. "How to set up an SSL certificate" with five steps is a HowTo. If you force HowTo onto a list of tips, Google will either ignore it or, worst case, hit you with a manual action for misleading markup.

Schema on articles without author and datePublished. BlogPosting without an author isn't a BlogPosting. Google doesn't treat it as a valid article, doesn't show it in Top Stories, doesn't count it as an E-E-A-T signal. Minimum: headline, author (Person with name), datePublished, image. Without those four fields, the block is useless.


How to Add and Verify

JSON-LD is an inline <script type="application/ld+json"> that goes into <head> or <body>. Google parses both, no difference in effect. By habit people put it in <head> because it's metadata.

In Next.js there are two paths. The first — the metadata API, starting with the App Router. In layout.tsx or page.tsx you export a metadata object, in which you can add an other → JSON-LD block. Convenient for typical cases — Organization, Website. The second — through dangerouslySetInnerHTML in the page itself. You build a JS object, run JSON.stringify, and inject it into a <script>. Convenient for dynamic schema — BlogPosting for a specific article, Product for a specific item, FAQPage with data from a CMS.

After adding it — verification is mandatory. Two tools:

Google Rich Results Testhttps://search.google.com/test/rich-results. Paste the URL or the raw code. Google shows which types it found, which fields are valid, and which rich results are available for the page. If it says "No items detected" — schema either didn't load or is invalid.

Schema.org Validatorhttps://validator.schema.org. Stricter; checks for conformance to the schema.org spec itself. Useful when you use an exotic type that Google doesn't yet support for rich results but that's semantically correct.

After publishing — monitor in Google Search Console. Performance → Search Appearance section. Google splits your impressions by snippet type: plain text, FAQ rich result, HowTo rich result, sitelinks. You can see which types actually work and which give no effect. If you added FAQPage and two months later "FAQ rich result" hasn't appeared in Search Appearance — that means Google didn't accept your markup, or the questions didn't pass the quality filter.


Bottom Line

Prioritization by impact on CTR and reach:

  1. BreadcrumbList — on everything that isn't the homepage. The simplest type, a visible effect in the SERP, no risk. If you have no schema anywhere — start here.
  2. Organization and Website — sitewide. Set it up once and it works across the whole site. Foundational signal for the Knowledge Graph and brand SERPs.
  3. BlogPosting / Product / Event — per-page. On every page of the matching type. This is E-E-A-T for articles and rich results for products and events.
  4. FAQPage — where appropriate. If you actually have an FAQ block with user-style questions. Don't force it just for the accordion.
  5. HowTo — only on real step-by-step guides. The strictest type in terms of quality, but also the most visible rich result.
  6. VideoObject, Review, Person — selectively. For specific content: video pages, reviews, author pages.

Schema.org is about controlling how Google sees and shows your site. By itself, schema won't push you into the top 10. But once you're in the top 10, schema lifts CTR through rich results, and your overall position climbs over 3–6 months on that very signal. It's one of the 30 SEO factors of 2026 people underrate. Everyone fusses over meta description and canonical tags, forgetting that rich results mean +50–200% visibility for the snippet in the results at the same position.

Start with BreadcrumbList and Organization. Add BlogPosting on articles. From there — play it by ear.

JSON-LD Schema.org: Which Types to Choose · hiregora.com