seo101

Structured Data

Structured data is machine-readable metadata describing what your content is - an article, a product, a recipe, an FAQ - using the schema.org vocabulary. It powers rich results (stars, prices, FAQs in the SERP), feeds knowledge panels, and gives answer engines and LLMs unambiguous facts to extract. It is the closest thing SEO has to a free lunch: deterministic, validatable, and directly tied to SERP enhancements.

JSON-LD: the format#

Google recommends JSON-LD - a script block, separate from your markup:

Article markup
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Fix Soft 404s in Next.js",
  "datePublished": "2026-03-02",
  "dateModified": "2026-05-19",
  "author": { "@type": "Person", "name": "Ada Okafor", "url": "https://example.com/authors/ada" },
  "image": "https://example.com/og/soft-404s.png"
}
</script>

In Next.js, render it from the page component so it ships with the server HTML:

app/blog/[slug]/page.tsx (excerpt)
export default async function Page({ params }: PageProps<"/blog/[slug]">) {
  const post = await getPost((await params).slug);
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: post.title,
    datePublished: post.publishedAt,
    author: { "@type": "Person", name: post.author.name },
  };
 
  return (
    <article>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* … */}
    </article>
  );
}

The types that earn rich results#

TypeRich resultUse on
Article / BlogPostingHeadline/date/author treatment, Top StoriesEditorial content
Product + Offer + AggregateRatingPrice, stock, starsProduct pages
FAQPageExpandable Q&A under your listingPages with genuine FAQs
HowToStep-by-step rich resultInstructional content
BreadcrumbListBreadcrumb trail instead of raw URLEverything
Organization / PersonKnowledge panel inputs, logoHome/about pages
LocalBusinessMap pack data: hours, locationLocal SEO
VideoObjectVideo thumbnails and key momentsPages embedding video

Two universal rules from Google's policies:

  1. Markup must describe visible page content. Marking up reviews that aren't on the page is a manual-action offense.
  2. Eligibility, not entitlement. Valid markup makes you eligible for a rich result; Google decides display per-query.

Entities and the graph#

Beyond rich results, structured data builds your entity graph - connecting your organization, authors and content to known entities. Use @id and sameAs to link identities:

{
  "@type": "Organization",
  "@id": "https://example.com/#org",
  "name": "Example Co",
  "url": "https://example.com",
  "logo": "https://example.com/logo.png",
  "sameAs": [
    "https://github.com/example",
    "https://www.linkedin.com/company/example",
    "https://en.wikipedia.org/wiki/Example_Co"
  ]
}

This disambiguation ("we are this Example, the one with this GitHub and this Wikipedia page") feeds knowledge panels and is increasingly relevant to how generative engines ground brand facts.

Validation and monitoring#

  • Rich Results Test - checks eligibility for Google's specific features.
  • Schema.org validator - general syntax/vocabulary validation.
  • Search Console → Enhancements - ongoing per-type error reports at scale; structured data breaks silently when templates change, so these reports are your alarm.

Next: JavaScript SEO - making sure all of this survives client-side rendering.