Structured Data and
Schema Markup

For Frontend Developers: SSR, CSR, and the AI Search Era


G Sriram

SDE III at HighLevel

React Nexus 2026 — Bengaluru
Slides QR Code

Scan to follow along

Same Website. Two Search Results.

Why are these different?

A
acme.com › products › headphones
Acme Pro Wireless Headphones | Acme
Acme Pro wireless headphones with active noise cancellation, 30-hour battery life, and premium sound quality.
A
acme.com › products › headphones
Acme Pro Wireless Headphones | Acme
★★★★★ 4.6 (1,247)
$199.00 · In stock · Active noise cancellation, 30-hour battery life, premium sound.

The difference: Schema Markup.

What is Schema Markup?

  • Shared vocabulary from Schema.org — founded by Google, Microsoft, Yahoo, Yandex
  • Tells engines what your content means, not just what it says
  • Format: JSON-LD in a <script> tag
  • No HTML changes (with JSON-LD) — sits separately in a script tag
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Acme Corp",
  "url": "https://acme.com",
  "logo": "https://acme.com/logo.png",
  "sameAs": [
    "https://twitter.com/acme",
    "https://linkedin.com/company/acme"
  ]
}
@context at the top level, @type on each entity

Back to Our Example

Behind those stars, that price, that "In stock" badge…

Without

A
acme.com › products › headphones
Acme Pro Wireless Headphones | Acme
Acme Pro wireless headphones with active noise cancellation, 30-hour battery life.

With

A
acme.com › products › headphones
Acme Pro Wireless Headphones | Acme
★★★★★ 4.6 (1,247)
$199.00 · In stock · Active noise cancellation, 30-hour battery life.
{
  "@context": "https://schema.org/",
  "@type": "Product",
  "name": "Acme Pro Wireless Headphones",
  "image": "https://acme.com/headphones.jpg",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": 4.6,
    "reviewCount": 1247
  },
  "offers": {
    "@type": "Offer",
    "price": 199.00,
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock"
  }
}
aggregateRating → stars + review count
offers → price + availability

Why Now: The AI Search Era

AI search is real. So is the confusion about schema's role in it.

✅  What schema IS for

Rich results — 25+ types

Star ratings, recipe cards, prices, breadcrumbs, videos in search results.

Knowledge Graph entries

Brand info panels — logo, socials, key entity data.

Content classification

Helps engines understand what type of content a page is.

All verified at developers.google.com/search/docs

❌  What schema is NOT for

A ranking factor

"...doesn't affect how the page ranks in Google web search"

— google.com/.../sd-policies

Required for AI Overviews

"no special schema.org structured data that you need to add"

— google.com/.../ai-features

Guaranteed AI search visibility

Google + Bing AI use schema (not required). Perplexity/ChatGPT: silent.

Schema is still worth shipping — for rich results, Knowledge Graph, and structured content. Just not ABSOLUTELY MANDATORY for AI search.

Schema markup only counts
if crawlers can see it.

Which rendering strategy delivers it most reliably?

Who Can See What

Crawler CSR / SPA SSR / SSG / RSC Executes JS?
Googlebot Eventually (queued) Immediately Yes, documented
Bingbot Eventually Immediately Yes (Edge engine)
GPTBot · OAI-SearchBot Not documented Immediately Not documented
PerplexityBot Not documented Immediately Not documented

Googlebot rendering: crawl → render → index. "Rendering happens when resources allow."

✅  Google + Bing only?

CSR can work. SSR is safer.

⚠  Need AI / non-JS crawlers?

Server-render — the only reliable path

Your Options, Ranked by Reliability

Option 1 — Server-rendered (best)

// Server Component (Next.js App Router)
export default async function Page() {
  const product = await getProduct()

  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.name,
  }

  const html = JSON.stringify(jsonLd).replace(/</g, '\\u003c')

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{ __html: html }}
    />
  )
}

Reaches: Every crawler immediately

Option 2 — JS-injected (CSR-compatible)

'use client'
import { Helmet } from 'react-helmet-async'
import { useEffect, useState } from 'react'

export default function ProductSchema() {
  const [product, setProduct] = useState(null)

  useEffect(() => {
    fetch('/api/product')
      .then(r => r.json())
      .then(setProduct)
  }, [])

  if (!product) return null

  return (
    <Helmet>
      <script type="application/ld+json">
        {JSON.stringify({
          '@context': 'https://schema.org',
          '@type': 'Product',
          name: product.name,
        })}
      </script>
    </Helmet>
  )
}

Reaches: Googlebot, Bingbot · GPTBot, PerplexityBot: not documented

Google docs: "Google Search can understand and process structured data that's available in the DOM when it renders the page."

Rendering Pitfalls

Even with the right rendering strategy, these embedding mistakes still ship in production.

The mistake Why it breaks (per docs)
Using next/script for JSON-LD
Common reflex in Next.js apps
Next.js docs: next/script is for executable JS. JSON-LD needs a native <script> tag.
Unsanitized JSON-LD output
XSS vector hiding in plain sight
JSON.stringify doesn't sanitize. Escape < to \u003c at minimum, or use serialize-javascript for full coverage.
SSG with dynamic data
Prices, inventory, event dates
Schema frozen at build time drifts from visible content. Google flags mismatches as misleading.
Schema that reads cookies / storage
User-specific or A/B-variant content
Google: "WRS does not retain state across page loads." Cookies, localStorage, session cleared between renders.

✅  The fix

Keep schema in Server Components · fetch data server-side · escape < to \u003c · revalidate often if using SSG

Sources: nextjs.org/docs/app/guides/json-ld · google.com/search/docs/.../generate-structured-data-with-javascript · google.com/search/docs/.../fix-search-javascript

Takeaways

  1. Schema makes pages eligible for rich results and Knowledge Graph

    Verified by Google. The AI search angle is mostly hype.

  2. Not a ranking factor · not required for AI Overviews

    Google says this explicitly. Don't oversell it.

  3. Pick rendering based on which crawlers you need

    Google & Bing: CSR can work (JS injection is documented), but SSR is safer. Everything else: server-render.

  4. Validate before shipping

    Google Rich Results Test · Schema Markup Validator · Search Console · @gsriram24/structured-data-validator for CI.

schema.org
developers.google.com/search/docs
nextjs.org/docs/app/guides/json-ld
search.google.com/test/rich-results
npm: @gsriram24/structured-data-validator
Linkbout QR Code

Slides, links & socials

Questions?