Skip to content

Structured data · Next.js (App Router)

How to add JSON-LD structured data in Next.js (App Router)

Structured data is what makes a result eligible for anything beyond a blue link, and it is increasingly how AI answer engines decide what your product is. A block that does not parse is discarded entirely, so you get none of the eligibility while the markup looks like it is there — a single trailing comma is enough.

The fix for Next.js (App Router)

13x detects your framework from the response and hands you this version rather than the generic one — below 50% confidence it hedges and gives you the generic one instead.

Render it from the page or layout. Building the object in code keeps it in sync with your real data:

tsx code
// app/page.tsx
export default function Page() {
  const schema = {
    "@context": "https://schema.org",
    "@type": "SoftwareApplication",
    name: "example.com",
    applicationCategory: "BusinessApplication",
    operatingSystem: "Web",
    url: "https://example.com",
  };

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

dangerouslySetInnerHTML is correct here — the content is your own config, not user input, and React would otherwise escape the JSON.

On a different stack? The general version of this fix explains what 13x checks and why it matters, without assuming a framework.

Check your Next.js (App Router) site

113 deterministic checks against your live URL, in about 30 seconds. Framework detected from the response, so every fix comes back in the form your stack actually uses.

No signup. Results in 30 seconds.