For Frontend Developers: SSR, CSR, and the AI Search Era
G Sriram
SDE III at HighLevel
Scan to follow along
Why are these different?
The difference: Schema Markup.
<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
Behind those stars, that price, that "In stock" badge…
Without
With
{
"@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
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.
Which rendering strategy delivers it most reliably?
| 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
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."
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-LDCommon 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
Verified by Google. The AI search angle is mostly hype.
Google says this explicitly. Don't oversell it.
Google & Bing: CSR can work (JS injection is documented), but SSR is safer. Everything else: server-render.
Google Rich Results Test ·
Schema Markup Validator ·
Search Console ·
@gsriram24/structured-data-validator
for CI.
Slides, links & socials
Questions?