Guides

How to Add JSON-LD in Next.js

JSON-LD structured data is added as a script tag rendered directly in the page — this covers the pattern for doing that safely and reusably across multiple page types.

Prerequisites

  • arrow_rightA Next.js App Router project
  • arrow_rightContent that genuinely matches a schema.org type (Article, Service, FAQPage, etc.)

Step 1: Render the Script Tag

export default function ArticlePage({ post }: { post: Post }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: post.title,
    datePublished: post.publishedAt,
  };
  return (
    <>
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
      <article>{/* ... */}</article>
    </>
  );
}

Step 2: Build a Reusable Helper

Rather than constructing the JSON-LD object inline on every page, a shared function that takes your content data and returns the correct schema object keeps the markup consistent and makes it far easier to fix a mistake across every page at once.

Common Errors

  • arrow_rightUsing JSON.stringify directly as children instead of dangerouslySetInnerHTML — React escapes text content, which corrupts the JSON
  • arrow_rightMarking up content that isn't actually visible on the page — this can trigger a manual action from Google for misleading structured data
  • arrow_rightForgetting to validate — always test output against Google's Rich Results Test before shipping

Security Considerations

  • arrow_rightNever interpolate unsanitized user input directly into the JSON-LD object — stringify it properly rather than building the string manually, which could otherwise allow script injection

Frequently Asked Questions

Where should the script tag be placed?add

Anywhere within the page or a shared layout — Next.js and search engines don't require it in a specific position, though keeping it near the content it describes is common practice for readability.

Can I add multiple JSON-LD blocks on one page?add

Yes — separate script tags for distinct schema types (e.g. Article plus BreadcrumbList) are valid and common.

How do I validate the output?add

Google's Rich Results Test and the Schema.org validator both accept a URL or raw markup and flag structural errors before you ship.

BUILDING SOMETHING SIMILAR?

If you'd rather have this built and shipped than build it yourself, I'm available for freelance and contract work.