Skip to content

Structured Data in Next.js: How JSON-LD Gets You Cited by Google and AI

Structured data is how you tell Google and AI what your page means, not just what it says. Here’s the Next.js way to ship it.

John Cravey with AIFounder10 min readUpdated Jul 6, 2026

Search engines and AI answer-engines read your page twice: once as words, and once as data. The words tell them what you wrote. The data — structured data, in the JSON-LD format — tells them what it means. That this is a business named Acme, in Plano, that repairs roofs, open until 6pm, rated 4.8. Ship it and you become eligible for rich results in Google and, increasingly, a citation in an AI answer. Skip it and you’re asking a machine to infer all of that from prose. The Next.js JSON-LD guide is refreshingly blunt about how to do it: render a `<script>` tag. This article is that guide, translated into a plan for whatever size you run.

Free estimate · 2 minutes

AI search is already sending buyers. Be citable.

Build the estimate to see the AI-visibility work we would ship for your site in the first thirty days. Sixty seconds, no opt-in.

What JSON-LD is, in one paragraph

JSON-LD is a small block of JSON that describes an entity using the shared vocabulary at schema.org. You embed it in your page inside a `<script type="application/ld+json">` tag. Google reads it to build rich results — the star ratings, FAQ drop-downs, breadcrumb trails, and business panels you see in search. AI systems increasingly read the same markup to decide what your page is about and whether to cite it. It’s the difference between a crawler guessing and a crawler being told.

The Next.js pattern: a script tag, rendered on the server

There’s no special API for this, and that’s deliberate — JSON-LD is data, not executable code, so a native `<script>` tag is the right tool, not the `next/script` component. You build a plain object, stringify it, and render it in your Server Component so it’s in the HTML the crawler receives on the first request.

// app/blog/[slug]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await getPost(slug);

  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: post.title,
    description: post.description,
    datePublished: post.publishedAt,
    author: { "@type": "Organization", name: "Acme Co" },
  };

  return (
    <article>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c"),
        }}
      />
      {/* …the article… */}
    </article>
  );
}

Type it so you can’t ship a broken schema

schema.org has hundreds of types and thousands of properties, and it’s easy to typo one into uselessness. The `schema-dts` package gives you TypeScript types for the whole vocabulary, so your editor autocompletes valid properties and the build fails if you invent one.

import type { Product, WithContext } from "schema-dts";

const jsonLd: WithContext<Product> = {
  "@context": "https://schema.org",
  "@type": "Product",
  name: "Standing Desk",
  image: "https://acme.co/desk.png",
  description: "Sit-stand desk, 5-year warranty.",
};

The schemas that actually earn something

You don’t need all of schema.org. Five types cover almost every business site, and each maps to a specific win:

  • Organization (or LocalBusiness) — in your root layout, once. Establishes the entity behind the whole site: name, logo, address, hours, contact. This is the anchor everything else links back to, and the single highest-value schema for a local business.
  • Article — on every blog post. Feeds the author, publish date, and headline that Google and AI use to attribute and cite your content.
  • Product — on product/service pages. Powers price, availability, and review rich results in shopping and search.
  • FAQPage — on any page with real Q&A. Earns the expandable FAQ rich result and gives AI engines clean, extractable question-answer pairs.
  • BreadcrumbList — on deep pages. Renders the breadcrumb trail in search and helps crawlers understand your site hierarchy.

Validate before you trust it

Never assume your markup is valid because it compiled. Paste a rendered URL into Google’s Rich Results Test to see exactly which rich results you’re eligible for, and the generic Schema Markup Validator to catch structural errors. Do this on a representative page of each type — one article, one product, one location — not every page. If the tool shows the entity and no errors, you’re done. And re-run it after any change to your content model or page templates, because a refactor that renames a field or restructures a component is exactly the kind of edit that silently breaks markup a validator would have caught in seconds.

A worked example: the local business panel

For a local business, one schema does most of the heavy lifting: `LocalBusiness`, in the root layout, describing the entity behind the whole site. Here’s what a real one looks like. The `@type` narrows to your category (`Roofer`, `Dentist`, `Plumber` — schema.org has hundreds), and the properties map to the business panel Google can show and the facts an AI answer can cite.

const jsonLd = {
  "@context": "https://schema.org",
  "@type": "Roofer",
  name: "Acme Roofing",
  image: "https://acme.co/storefront.jpg",
  telephone: "+1-972-555-0100",
  address: {
    "@type": "PostalAddress",
    streetAddress: "100 Main St",
    addressLocality: "Plano",
    addressRegion: "TX",
    postalCode: "75024",
  },
  openingHours: "Mo-Fr 08:00-18:00",
  aggregateRating: {
    "@type": "AggregateRating",
    ratingValue: "4.8",
    reviewCount: "312",
  },
};

Ship that once and you become eligible for the rich business treatment in search and a clean, machine-readable summary of who you are — name, location, hours, rating — for any AI system deciding whether to recommend you. Follow Google’s local business structured-data guidelines for the exact required and recommended properties; the closer you match them, the more of the rich result you unlock. One rule: the facts in your schema must match what’s visible on the page. Marking up a 4.8 rating you don’t display, or hours that contradict your footer, is exactly the kind of mismatch that gets structured data ignored or penalized.

Where structured data and AI answers meet

The reason structured data matters more every quarter is that the surfaces reading it are multiplying. It used to be Google alone, building rich results. Now every AI answer-engine that summarizes “who’s a good X near me” or “what does Y cost” is reading the same signals to decide what your business is and whether it’s a confident enough answer to cite. A page that spells out its entity — this is a business, here’s its name, category, location, and the questions it answers — is far easier for a model to represent correctly than a wall of prose it has to interpret. That’s why the two schemas we push hardest for local businesses are `LocalBusiness` (who you are) and `FAQPage` (the exact questions buyers ask, in clean question-answer pairs a model can lift directly). Google documents the FAQ structured-data format precisely; matching it is what turns your FAQ into an extractable answer instead of buried text. We go deeper on the answer-engine strategy in our AEO write-up, and it pairs directly with the outward-facing map you hand AI in AGENTS.md and llms.txt.

Keeping schema honest as the site changes

Structured data has one failure mode that’s worse than not having it: having it and letting it go stale. If your markup claims hours you’ve since changed, a rating you no longer display, a price that moved, or an author who left, you’ve created a mismatch between what the machine reads and what the human sees. Google’s structured-data policies are explicit that markup must reflect the visible content of the page, and violating that can get your rich results suppressed or, in bad cases, earn a manual action. So the rule is simple: generate schema from the same data that renders the page, never hand-write it as a parallel copy that can drift.

When your schema is generated — Article from your post data, LocalBusiness from your business record, Product from your catalog — it can’t contradict the page, because it’s reading the same source. That’s the real reason we push generated schema over hand-authored blocks: not just convenience, but correctness that survives every content edit. Set a light cadence to re-validate: run your top page of each type through the Rich Results Test once a quarter and after any change to your content model. If you display reviews, keep the aggregate rating in the markup tied to the real review data, not a number someone typed in once. Treat structured data as a live contract with the machines reading your site, and it keeps paying off. Let it rot, and it turns from an asset into a liability that’s hard to even notice, because nothing on the page looks broken. The teams that win with schema aren’t the ones who add the most types; they’re the ones whose markup never lies, because it’s wired to the same data the page renders and re-checked on a cadence rather than set once and forgotten.

What this means for your business

The markup is universal; the strategy scales with how many pages and entities you manage.

For agencies

Structured data is a repeatable, defensible line item. Build a typed schema module into your Next.js starter — `buildOrganizationJsonLd`, `buildArticleJsonLd`, `buildLocalBusinessJsonLd` — and every client site ships correct markup by construction. That consistency is your moat: it’s the difference between “we added some schema” and “every page on every client site resolves to a validated entity.” Offer a structured-data audit as a paid discovery for prospects — most sites you’ll audit have none, or have invalid markup a validator flags in seconds, and that gap sells the engagement. Wire the Article schema to the client’s Organization `@id` so their author authority compounds across their whole blog.

For micro businesses (1–5 people)

One schema matters more than all the others for you: LocalBusiness, in your root layout, with your real name, address, phone, and hours. That single block is what makes you eligible for the business panel and map treatment that local searchers actually click. Add FAQPage markup to your top service page — take the five questions customers actually ask and mark them up — and you become extractable by AI answers for exactly the queries your buyers type. It’s maybe an hour of work for the two schemas that move the needle for a local shop. Everything else is optional until you have more pages.

For small businesses (SMEs)

You have enough pages that structured data should be generated from your content, not hand-written. Emit Article schema from your blog data, Product or Service schema from your services data, and LocalBusiness once for the whole site. The leverage is that new content ships correct markup automatically — publish a post, get valid Article schema for free. Run the Rich Results Test on one page of each type after you wire it, then trust the generator. If you sell products or take reviews, the Product and review schemas can put stars in your search listing, which lifts click-through on the pages where it appears.

For mid-size companies

Your challenge is scale and correctness across thousands of pages and multiple content systems. Centralize schema generation in one typed module, validate it in CI (schema-dts turns invalid markup into a build failure, which is exactly what you want at this scale), and define entity relationships deliberately — every Article `author` and every page `publisher` pointing at one canonical Organization `@id`, so your entity graph is coherent rather than a thousand disconnected snippets. This is where structured data stops being an SEO tactic and becomes part of how AI systems model your brand. Treat it like the data contract it is, with ownership, tests, and a validator in the pipeline.

How we run this at Frontend Horizon

Every FH site emits an Organization entity site-wide, Article schema on every post wired to that Organization, and LocalBusiness plus FAQ markup where the business is local. It’s generated from a single typed module and validated, so it can’t silently rot. If you want to know what rich results and AI citations your current markup is leaving on the table, run a free discovery — we’ll validate your top pages and show you the gaps. Keep reading: the metadata playbook covers the words half of the equation, and sitemaps and robots.txt make sure crawlers reach the pages your schema describes.

Answers

Frequently asked questions

What is JSON-LD in one paragraph?

A block of structured facts about the page, written in a standard vocabulary and embedded in the HTML for machines rather than readers. It tells a search engine what a page is about explicitly, instead of leaving it to infer from prose.

How should it be added in a Next.js app?

As a script tag rendered on the server, built from the same data the page renders. Generating it client-side means the crawler may not see it, and hand-writing it means it goes stale the first time the page content changes.

How do I stop shipping a broken schema?

Type the object so a missing required field is a compile error rather than a silent omission. Structured data fails quietly: nothing errors, the rich result simply never appears, which is the worst kind of bug to leave to review.

Which schema types actually earn something?

For a business site: Organization or LocalBusiness, Service or Product, FAQ, and Breadcrumb. Those four map to real rich results and to facts an answer engine can extract. The rest of the vocabulary is mostly unused by anything that matters.

Does structured data improve rankings?

Not directly. It makes you eligible for rich results and helps engines extract facts confidently, which affects how you appear rather than where. Treating it as a ranking lever leads to marking up everything, which produces no benefit and some risk.

How do I validate it?

Through the rich results test and the schema validator, on the rendered page rather than the source. Both catch structural errors. Neither catches the more common problem, which is markup describing something the page does not actually say.

How does structured data relate to AI answers?

It gives an answer engine facts it can lift with confidence rather than inferring them from prose. It is not a citation mechanism, and being marked up does not make you quotable. The content still decides that; the markup removes ambiguity about what the content asserts.

How do I keep schema honest as the site changes?

By generating it from the page's own data rather than maintaining it separately. The failure mode is a price, an address, or an opening time in the markup that no longer matches the page, which is both a quality problem and a policy violation.

Can marking up the wrong things hurt?

Yes. Markup describing content not visible on the page is against the guidelines and can cost you rich-result eligibility entirely. The rule is that the structured data describes what a reader can see, not what you wish the page said.

Does FAQ markup still produce rich results?

Display has been reduced for most sites, and the markup remains worth having because it helps engines extract answers cleanly. Judge it by whether the answers are quotable rather than by whether a rich result appears, which is outside your control.

What is the local-business panel example?

Marking up the business name, address, hours, service area, and services so the details appear consistently and can be extracted. For a service business it is the single highest-return schema, because those facts are what a local searcher needs.

Where should I start?

Organization or LocalBusiness on the site, then Service on each service page, then FAQ where you have real questions answered. That order matches the return, and it is a day of work rather than a project.

Question we did not answer? Ask us directly and we will answer it here.

John Cravey, Founder
Written by
John Cravey
Founder

Founder of Frontend Horizon. Writes most of the long-form work on the FH blog.

Newer post
Titles, Meta Descriptions, and Social Cards: The Next.js Metadata Playbook for Every Business Size
Older post
AEO for Micro Businesses: Get Named in AI Answers Without a Marketing Team
Keep reading

More from the blog

SEO·5 min

SEO for AI: How to Rank When the Search Engine Is an Answer Engine

More of your buyers get their answer from an AI than from page one. The playbook for being that answer is concrete, and most of your competitors have not run it.

SEO·5 min

Google SEO: How Ranking Works From Crawl to AI Overviews

Rankings are not granted. They are computed, by systems with documented jobs. Understand the jobs and SEO stops feeling like weather.

SEO·10 min

On-Page SEO Automation: Titles, Meta, Schema, and Internal Links

The boring on-page work is where most SEO is won and lost. It is also exactly the work AI does faster than you and never forgets.