Aarunya AppsAarunya Apps
๐Ÿ” SEO9 min readยทJune 28, 2026

How to Add Structured Data to Your Next.js App (JSON-LD Guide)

Structured data (JSON-LD) tells Google what your page is about โ€” enabling rich results like FAQ dropdowns, star ratings, event dates, and article bylines directly in search results. Here's how to add it correctly in Next.js 14+ App Router.

The pattern: script tag with dangerouslySetInnerHTML

JSON-LD goes inside a <script type="application/ld+json"> tag. In the Next.js App Router, place it directly in your page or layout component:

// app/page.tsx (or any page/layout)
export default function Page() {
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "WebSite",
    name: "Your Site",
    url: "https://yoursite.com",
  }

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* rest of your page */}
    </>
  )
}

FAQPage schema (most useful for SEO)

const faqLd = {
  "@context": "https://schema.org",
  "@type": "FAQPage",
  mainEntity: faqItems.map(({ q, a }) => ({
    "@type": "Question",
    name: q,
    acceptedAnswer: { "@type": "Answer", text: a },
  })),
}

FAQPage schema can double your SERP real estate by showing expandable Q&A directly under your search result. It works best on pages that already have visible FAQ content.

Article schema for blog posts

// app/blog/[slug]/page.tsx
const articleLd = {
  "@context": "https://schema.org",
  "@type": "Article",
  headline: post.title,
  description: post.description,
  url: `https://yoursite.com/blog/${post.slug}`,
  datePublished: post.date,
  dateModified: post.updatedAt ?? post.date,
  author: { "@type": "Person", name: "Your Name" },
  publisher: {
    "@type": "Organization",
    name: "Your Site",
    logo: { "@type": "ImageObject", url: "https://yoursite.com/logo.png" },
  },
}

BreadcrumbList (improves site structure signals)

const breadcrumbLd = {
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  itemListElement: [
    { "@type": "ListItem", position: 1, name: "Home", item: "https://yoursite.com" },
    { "@type": "ListItem", position: 2, name: "Blog", item: "https://yoursite.com/blog" },
    { "@type": "ListItem", position: 3, name: post.title, item: `https://yoursite.com/blog/${post.slug}` },
  ],
}

Multiple schemas on one page

You can โ€” and should โ€” include multiple JSON-LD blocks on a single page. Each gets its own <script> tag:

return (
  <>
    <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(articleLd) }} />
    <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbLd) }} />
    <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(faqLd) }} />
    {/* page content */}
  </>
)

Validation

After deploying, test your structured data at search.google.com/test/rich-results. It shows exactly which rich results your page is eligible for and flags any missing required fields.

To generate the JSON-LD without writing it by hand, use the Schema.org JSON-LD Generator โ€” free, no account required.

Try the related tool

Schema.org JSON-LD Generator โ€” free, runs 100% in your browser.

Open Schema.org JSON-LD Generator โ†’

Enjoyed this? Get notified when Pro launches.