Rocky_Mountain_Vending/components/review-schema.tsx
DMleadgen 46d973904b
Initial commit: Rocky Mountain Vending website
Next.js website for Rocky Mountain Vending company featuring:
- Product catalog with Stripe integration
- Service areas and parts pages
- Admin dashboard with Clerk authentication
- SEO optimized pages with JSON-LD structured data

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 16:22:15 -07:00

90 lines
2.2 KiB
TypeScript

import { businessConfig } from "@/lib/seo-config"
interface Review {
author?: string
rating?: number
reviewBody?: string
datePublished?: string
}
interface ReviewSchemaProps {
aggregateRating?: {
ratingValue: number
reviewCount: number
bestRating?: number
worstRating?: number
}
reviews?: Review[]
}
/**
* Review Schema Component
* Implements AggregateRating and Review schema markup for SEO
* Based on review data from reputation hub and Google reviews
*/
export function ReviewSchema({ aggregateRating, reviews }: ReviewSchemaProps) {
if (!aggregateRating && (!reviews || reviews.length === 0)) {
return null
}
const structuredData: any = {
"@context": "https://schema.org",
"@type": "AggregateRating",
}
if (aggregateRating) {
structuredData.ratingValue = aggregateRating.ratingValue
structuredData.reviewCount = aggregateRating.reviewCount
structuredData.bestRating = aggregateRating.bestRating || 5
structuredData.worstRating = aggregateRating.worstRating || 1
}
// If we have individual reviews, create a full Review schema
if (reviews && reviews.length > 0) {
const reviewItems = reviews.map((review) => ({
"@type": "Review",
author: {
"@type": "Person",
name: review.author || "Customer",
},
reviewRating: review.rating
? {
"@type": "Rating",
ratingValue: review.rating,
bestRating: 5,
worstRating: 1,
}
: undefined,
reviewBody: review.reviewBody,
datePublished: review.datePublished,
}))
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "LocalBusiness",
name: businessConfig.name,
aggregateRating: structuredData,
review: reviewItems,
}),
}}
/>
</>
)
}
// Just aggregate rating
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
)
}