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>
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
import { businessConfig, serviceAreas, businessHours, socialProfiles } from "@/lib/seo-config"
|
|
|
|
interface StructuredDataProps {
|
|
type?: "LocalBusiness" | "Service" | "Organization"
|
|
additionalData?: Record<string, unknown>
|
|
}
|
|
|
|
/**
|
|
* Structured Data Component for LocalBusiness/Service/Organization
|
|
* Implements JSON-LD schema for SEO and rich results
|
|
* Enhanced with AggregateRating and Organization schema for better SEO
|
|
*/
|
|
export function StructuredData({ type = "LocalBusiness", additionalData }: StructuredDataProps) {
|
|
// Build opening hours specification
|
|
const openingHoursSpecification = [
|
|
{
|
|
"@type": "OpeningHoursSpecification",
|
|
dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
|
|
opens: businessHours.monday.open,
|
|
closes: businessHours.monday.close,
|
|
},
|
|
]
|
|
|
|
// Build area served (detailed list of cities)
|
|
const areaServed = serviceAreas.map((area) => ({
|
|
"@type": "City",
|
|
name: area.city,
|
|
addressRegion: area.state,
|
|
addressCountry: area.country,
|
|
}))
|
|
|
|
const structuredData = {
|
|
"@context": "https://schema.org",
|
|
"@type": type,
|
|
name: businessConfig.name,
|
|
legalName: businessConfig.legalName,
|
|
description: businessConfig.description,
|
|
url: businessConfig.website,
|
|
telephone: businessConfig.phoneFormatted,
|
|
email: businessConfig.email,
|
|
foundingDate: businessConfig.openingDate,
|
|
// Service business - no physical address
|
|
areaServed: areaServed,
|
|
serviceArea: {
|
|
"@type": "GeoCircle",
|
|
// Approximate center of service area (Salt Lake City area)
|
|
geoMidpoint: {
|
|
"@type": "GeoCoordinates",
|
|
latitude: 40.7608,
|
|
longitude: -111.891,
|
|
},
|
|
// Approximate radius covering all service areas
|
|
geoRadius: {
|
|
"@type": "Distance",
|
|
value: 50,
|
|
unitCode: "mi",
|
|
},
|
|
},
|
|
openingHoursSpecification: openingHoursSpecification,
|
|
priceRange: "$$",
|
|
// Aggregate rating based on website content (4.9 average, 50+ reviews)
|
|
aggregateRating: {
|
|
"@type": "AggregateRating",
|
|
ratingValue: 4.9,
|
|
reviewCount: 50,
|
|
bestRating: 5,
|
|
worstRating: 1,
|
|
},
|
|
// Social profiles
|
|
sameAs: [
|
|
socialProfiles.linkedin,
|
|
socialProfiles.facebook,
|
|
socialProfiles.youtube,
|
|
socialProfiles.twitter,
|
|
],
|
|
// Logo
|
|
logo: {
|
|
"@type": "ImageObject",
|
|
url: `${businessConfig.website}/rmv-logo.png`,
|
|
},
|
|
// Image
|
|
image: {
|
|
"@type": "ImageObject",
|
|
url: `${businessConfig.website}/images/rocky-mountain-vending-service-area-926x1024.webp`,
|
|
},
|
|
// Additional data if provided
|
|
...(additionalData || {}),
|
|
}
|
|
|
|
return (
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
|
|
/>
|
|
)
|
|
}
|
|
|