Careeroza
JSON-LD
Structured Data
JSON-LD tells Google exactly what a page is about (a product with a price, rating, availability). It enables rich results: stars and price shown directly in search. Render it as a script tag in the page:
export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
const product = await getProduct(Number((await params).id));
if (!product) notFound();
const jsonLd = productJsonLd(product);
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd).replace(/</g, '\\u003c') }}
/>
<h1>{product.name}</h1>
</>
);
}Note: The replace(/</g, ...) escapes < so a product name containing </script> cannot break out of the tag (XSS).
Building the Object
Example
type Product = { id: number; name: string; price: number; stock: number; rating: number; reviews: number; image: string };
function productJsonLd(p: Product) {
return {
'@context': 'https://schema.org',
'@type': 'Product',
name: p.name,
image: p.image,
offers: {
'@type': 'Offer',
price: p.price.toFixed(2),
priceCurrency: 'INR',
availability: 'https://schema.org/' + (p.stock > 0 ? 'InStock' : 'OutOfStock'),
},
aggregateRating: { '@type': 'AggregateRating', ratingValue: p.rating, reviewCount: p.reviews },
};
}
const ld = productJsonLd({ id: 42, name: 'Redmi Note 14 5G', price: 17999, stock: 12, rating: 4.3, reviews: 12480, image: 'https://cdn.shopease.in/p/42.jpg' });
console.log(JSON.stringify(ld, null, 2));Output
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Redmi Note 14 5G",
"image": "https://cdn.shopease.in/p/42.jpg",
"offers": {
"@type": "Offer",
"price": "17999.00",
"priceCurrency": "INR",
"availability": "https://schema.org/InStock"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.3,
"reviewCount": 12480
}
}