All guidesAI visibility and the agentic web

JSON-LD Structured Data for AI and Search Engines

JSON-LD structured data uses Schema.org vocabulary to describe your content in a machine-readable format that both search engines and AI models parse with high confidence. By adding JSON-LD script tags for Organization, Article, FAQPage, and other types, you enable rich search results and give AI models unambiguous understanding of your pages.

By Paul Gosnell Updated March 2026 11 min read

p0stman builds for the agentic web. AgentReady scans your site for llms.txt, structured data and crawler access in under a minute, free.

When an AI model processes a web page, it must determine what the page is about, who wrote it, when it was published, what questions it answers, and how it relates to the broader topic. Without structured data, the model infers all of this from the raw HTML -- reading headings, paragraphs, and page structure to build an understanding. This works, but it is imprecise and error-prone.

Structured data eliminates the guesswork. A JSON-LD script tag in your page's head explicitly declares: this is an Article, written by this person, published on this date, about this topic, with these FAQ items. The model reads this declaration and treats it as ground truth. No inference required, no ambiguity.

For search engines, structured data has been important for years -- it enables rich results like FAQ dropdowns, star ratings, and recipe cards. For AI models, it is becoming equally critical. As AI-generated search results (Google AI Overviews, ChatGPT search, Perplexity answers) replace traditional blue links, the pages with the clearest structured data get cited most reliably. This guide covers every Schema.org type you need, with complete examples and framework-specific implementation patterns. Use our AgentReady scanner to check your site's current structured data.

What is JSON-LD?

JSON-LD stands for JavaScript Object Notation for Linked Data. It is a standard for encoding structured information in JSON format, using vocabulary from Schema.org, a collaborative project maintained by Google, Microsoft, Yahoo, and Yandex.

JSON-LD is embedded in your page as a <script type="application/ld+json"> tag, typically in the <head> section. It does not affect the visual presentation of the page. Search engines and AI crawlers read it separately from the visible content.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Your Company",
  "url": "https://yourdomain.com",
  "description": "What your company does"
}
</script>

Every JSON-LD block requires two fields: @context (always "https://schema.org") and @type (the Schema.org type you are declaring). Everything else depends on the type.

Why JSON-LD over Microdata or RDFa

There are three formats for structured data: JSON-LD, Microdata, and RDFa. Google explicitly recommends JSON-LD for several reasons:

  • Separation of concerns. JSON-LD lives in a script tag, completely separate from your HTML markup. You can add, modify, or remove structured data without touching your page layout.
  • Easier maintenance. A single JSON block is easier to read, validate, and update than attributes scattered across dozens of HTML elements.
  • Dynamic generation. JSON-LD can be generated programmatically from your data layer, which is essential for CMS-driven pages and dynamic content.
  • Framework compatibility. Works identically in React, Vue, Svelte, static HTML, and server-rendered pages.

Essential Schema.org types

Organization

Place on your homepage. Declares your company identity, contact information, and social profiles. This is the foundation that other schemas reference.

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "p0stman",
  "url": "https://p0stman.com",
  "logo": "https://p0stman.com/logo.png",
  "description": "AI-powered product studio building websites, AI agents, and mobile apps",
  "foundingDate": "2019",
  "founder": {
    "@type": "Person",
    "name": "Paul Gosnell"
  },
  "address": {
    "@type": "PostalAddress",
    "addressLocality": "London",
    "addressCountry": "GB"
  },
  "contactPoint": {
    "@type": "ContactPoint",
    "email": "hello@p0stman.com",
    "contactType": "sales"
  },
  "sameAs": [
    "https://twitter.com/paulgosnell",
    "https://linkedin.com/in/pgosnell",
    "https://github.com/paulgosnell"
  ]
}

WebSite

Also on the homepage. Declares the site name and search action, which enables the sitelinks search box in Google results:

{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "p0stman",
  "url": "https://p0stman.com",
  "potentialAction": {
    "@type": "SearchAction",
    "target": "https://p0stman.com/search?q={search_term_string}",
    "query-input": "required name=search_term_string"
  }
}

Article

For blog posts, guides, and any long-form content. This is one of the most important types for AI visibility because it explicitly declares authorship, publication date, and content summary.

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Build an A2A Agent Endpoint",
  "description": "Complete guide to implementing the Agent-to-Agent protocol...",
  "url": "https://p0stman.com/guides/a2a-agent-guide.html",
  "image": "https://p0stman.com/images/a2a-guide-og.png",
  "author": {
    "@type": "Person",
    "name": "Paul Gosnell",
    "url": "https://p0stman.com/paulgosnell"
  },
  "publisher": {
    "@type": "Organization",
    "name": "p0stman",
    "url": "https://p0stman.com",
    "logo": {
      "@type": "ImageObject",
      "url": "https://p0stman.com/logo.png"
    }
  },
  "datePublished": "2026-03-12",
  "dateModified": "2026-03-12",
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://p0stman.com/guides/a2a-agent-guide.html"
  }
}

FAQPage

For any page with a Frequently Asked Questions section. This is extremely valuable because Google displays FAQ questions directly in search results as expandable dropdowns, and AI models use FAQ answers as authoritative, quotable text.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "How much does a website cost?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "A simple marketing website starts from GBP 3,000. Complex web applications with custom features, AI integration, and database architecture typically range from GBP 10,000 to GBP 20,000."
      }
    },
    {
      "@type": "Question",
      "name": "How long does a project take?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Simple websites take 2-4 weeks. Complex platforms take 6-12 weeks. We provide a detailed timeline estimate during the discovery call."
      }
    }
  ]
}

HowTo

For step-by-step guides and tutorials. Enables rich results with step numbers and estimated time:

{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to Add JSON-LD Structured Data to Your Website",
  "description": "Step-by-step guide to implementing Schema.org JSON-LD...",
  "totalTime": "PT30M",
  "step": [
    {
      "@type": "HowToStep",
      "position": 1,
      "name": "Choose your Schema.org types",
      "text": "Identify which Schema.org types match your content..."
    },
    {
      "@type": "HowToStep",
      "position": 2,
      "name": "Create the JSON-LD blocks",
      "text": "Write the JSON-LD for each schema type..."
    },
    {
      "@type": "HowToStep",
      "position": 3,
      "name": "Add to your page head",
      "text": "Insert the script tags into your HTML head..."
    }
  ]
}

SoftwareApplication / WebApplication

For SaaS products, tools, and web applications:

{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "AgentReady Scanner",
  "url": "https://p0stman.com/agentready",
  "description": "Free AI readiness audit tool that scans your website...",
  "applicationCategory": "DeveloperApplication",
  "operatingSystem": "Web",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD"
  },
  "creator": {
    "@type": "Organization",
    "name": "p0stman"
  }
}

BreadcrumbList

Declares the navigation hierarchy of a page. Helps search engines and AI understand your site structure:

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://p0stman.com"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Guides",
      "item": "https://p0stman.com/guides/"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Structured Data Guide",
      "item": "https://p0stman.com/guides/structured-data-guide.html"
    }
  ]
}

Multiple schemas per page

A single page can (and should) include multiple JSON-LD blocks. Each goes in its own <script type="application/ld+json"> tag. A typical guide page might include:

  1. Article -- declaring the content, author, and dates
  2. BreadcrumbList -- declaring the navigation path
  3. FAQPage -- declaring the FAQ section questions and answers

Google processes each schema independently. There is no limit to the number of schemas per page, though each must be valid and relevant to the page content.

Implementing JSON-LD in Next.js

App Router (recommended)

In Next.js App Router, render the JSON-LD directly in your component. Because Server Components render on the server, the script tag is in the initial HTML response:

// app/blog/[slug]/page.tsx
export default async function BlogPost({ params }) {
  const post = await getPost(params.slug);

  const articleSchema = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: post.title,
    description: post.excerpt,
    url: `https://yourdomain.com/blog/${params.slug}`,
    author: {
      "@type": "Person",
      name: post.author.name,
    },
    datePublished: post.publishedAt,
    dateModified: post.updatedAt,
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(articleSchema),
        }}
      />
      <article>
        <h1>{post.title}</h1>
        <div>{post.content}</div>
      </article>
    </>
  );
}

Layout-level schemas

For schemas that appear on every page (Organization, WebSite), add them in your root layout:

// app/layout.tsx
export default function RootLayout({ children }) {
  const orgSchema = {
    "@context": "https://schema.org",
    "@type": "Organization",
    name: "Your Company",
    url: "https://yourdomain.com",
    logo: "https://yourdomain.com/logo.png",
  };

  return (
    <html lang="en">
      <head>
        <script
          type="application/ld+json"
          dangerouslySetInnerHTML={{
            __html: JSON.stringify(orgSchema),
          }}
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Reusable schema helpers

Create utility functions to generate schemas consistently across pages:

// lib/schema.ts
export function articleSchema({
  title,
  description,
  url,
  authorName,
  publishedAt,
  modifiedAt,
}: {
  title: string;
  description: string;
  url: string;
  authorName: string;
  publishedAt: string;
  modifiedAt?: string;
}) {
  return {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: title,
    description,
    url,
    author: { "@type": "Person", name: authorName },
    publisher: {
      "@type": "Organization",
      name: "Your Company",
      url: "https://yourdomain.com",
      logo: {
        "@type": "ImageObject",
        url: "https://yourdomain.com/logo.png",
      },
    },
    datePublished: publishedAt,
    dateModified: modifiedAt || publishedAt,
    mainEntityOfPage: { "@type": "WebPage", "@id": url },
  };
}

export function faqSchema(
  questions: Array<{ question: string; answer: string }>
) {
  return {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    mainEntity: questions.map((q) => ({
      "@type": "Question",
      name: q.question,
      acceptedAnswer: {
        "@type": "Answer",
        text: q.answer,
      },
    })),
  };
}

How AI models use structured data differently from search engines

Search engines like Google use structured data primarily to generate rich results -- visual enhancements to search listings like star ratings, FAQ dropdowns, recipe cards, and event details. The structured data improves the presentation of your listing but does not directly affect ranking.

AI models use structured data differently. They use it to build confidence in their understanding of your content. When an AI model sees an Article schema with a specific headline, author, and date, it treats these as confirmed facts rather than inferences. This makes the model more likely to cite your content accurately and confidently in its responses.

Specifically, AI models benefit from structured data in these ways:

  • Entity disambiguation. Organization schema tells the AI exactly what your company is called, eliminating confusion with similarly-named entities.
  • Authorship attribution. Article schema with author information helps AI models cite the correct source.
  • Freshness signals. datePublished and dateModified help AI models prioritise recent content over outdated information.
  • FAQ extraction. FAQPage schema provides pre-structured question-answer pairs that AI models can quote directly, often verbatim.
  • Content categorisation. The @type field helps AI models understand what kind of content they are processing (article, product, how-to, FAQ).

Testing and validation

Google Rich Results Test

Visit search.google.com/test/rich-results and enter your page URL. Google fetches the page, parses all JSON-LD blocks, and reports any errors or warnings. It also shows which rich result types your page is eligible for.

Schema.org Validator

Visit validator.schema.org and paste your JSON-LD code or page URL. This validates against the full Schema.org specification, which is broader than what Google supports. Useful for catching structural errors.

Manual verification with curl

# Extract all JSON-LD from a page
curl -s https://yourdomain.com | grep -o '<script type="application/ld+json">[^<]*</script>'

# Pretty-print with jq (if installed)
curl -s https://yourdomain.com | \
  grep -oP '(?<=<script type="application/ld\+json">).*?(?=</script>)' | \
  jq .

AgentReady scanner

The AgentReady scanner checks for structured data as part of a comprehensive AI readiness audit. It verifies that your schemas are valid, checks for essential types (Organization, Article), and reports missing schemas alongside other AI visibility factors.

Common mistakes

Missing required properties

Each schema type has required and recommended properties. An Article without headline or author will generate errors. Always check the Google structured data documentation for required fields before implementing a new type.

Schema content not matching page content

Google explicitly warns against structured data that does not match the visible page content. If your Article schema says the headline is "Best AI Tools 2026" but the actual page heading is different, this is a policy violation that can result in manual penalties.

Outdated dates

If your dateModified says 2024 but the content clearly references 2026 events, both search engines and AI models may distrust the freshness signal. Keep dates accurate and update dateModified when you revise content.

Invalid JSON

Trailing commas, unescaped quotes in text values, and missing closing braces are common JSON syntax errors. Always validate your JSON-LD with a JSON linter before deploying.

Schema implementation checklist

  1. Homepage: Organization + WebSite schemas
  2. Blog posts / guides: Article + BreadcrumbList + FAQPage (if FAQ section exists)
  3. Product / tool pages: WebApplication or SoftwareApplication
  4. How-to pages: HowTo + Article + BreadcrumbList
  5. Service pages: Service or Article + BreadcrumbList
  6. All pages: BreadcrumbList (navigation context)

For a comprehensive AI readiness audit that includes structured data validation, use the AgentReady scanner. It checks schemas alongside robots.txt, SSR rendering, meta tags, and other visibility factors.

Frequently Asked Questions

What is JSON-LD structured data?

JSON-LD (JavaScript Object Notation for Linked Data) is a method of encoding structured data using JSON. It uses Schema.org vocabulary to describe entities like organizations, articles, products, and events in a format that search engines and AI models can parse unambiguously. JSON-LD is embedded in a script tag in the page head and does not affect the visual presentation of the page.

Why does structured data matter for AI models?

AI models use structured data to understand page content with higher confidence than parsing HTML. When a page includes Organization schema, the AI knows the company name, URL, and description with certainty rather than inferring them from page layout. This leads to more accurate AI-generated responses and increases the likelihood of your content being cited in AI conversations and search results.

Which Schema.org types should I implement?

At minimum: Organization on your homepage, Article on blog posts, and FAQPage on pages with FAQ sections. For SaaS products, add WebApplication or SoftwareApplication. For how-to guides, add HowTo. For product pages, add Product. The specific types depend on your content, but Organization and Article cover the majority of use cases.

Can I have multiple JSON-LD schemas on one page?

Yes. You can include multiple JSON-LD script tags on a single page, each containing a different schema type. A blog post page might include Article, BreadcrumbList, FAQPage, and Organization schemas simultaneously. Google and AI crawlers process all of them independently. There is no practical limit to the number of schemas per page.

How do I test my structured data?

Use Google's Rich Results Test at search.google.com/test/rich-results to validate your schemas and check for errors. The Schema.org Validator at validator.schema.org checks compliance with the Schema.org specification. For AI-specific validation, the AgentReady scanner checks for structured data as part of a complete AI readiness audit.

What is the difference between JSON-LD, Microdata, and RDFa?

JSON-LD, Microdata, and RDFa are three formats for embedding structured data in web pages. JSON-LD uses a script tag separate from the HTML content, making it easiest to implement and maintain. Microdata uses HTML attributes inline with content elements. RDFa also uses HTML attributes. Google recommends JSON-LD because it is easier to implement, maintain, and does not interleave with your HTML markup.

Does structured data directly affect search rankings?

Structured data is not a direct ranking factor for Google search. However, it enables rich results (featured snippets, FAQ dropdowns, star ratings) which significantly increase click-through rates -- sometimes by 30% or more. For AI models, structured data improves the accuracy of citations and recommendations, which indirectly drives more referral traffic to your site.

How do I implement JSON-LD in Next.js?

In Next.js App Router, render a <script type="application/ld+json"> tag directly in your Server Component using dangerouslySetInnerHTML with JSON.stringify(). For schemas that appear on every page, add them in your root layout. For page-specific schemas, add them in the page component. The script tag is server-rendered, so it is present in the initial HTML response for all crawlers.

Related Guides

Paul Gosnell, founder of p0stman

Paul Gosnell · Founder, p0stman

Want to know how AI agents see your site?

AgentReady checks your site for the signals in this guide and tells you exactly what to fix. Free, no signup, results in under a minute.

Scan your site Free scan. No signup.