import type { Metadata } from 'next'; /** * Clean HTML entities from text (e.g., & -> &, " -> ") */ function cleanHtmlEntities(text: string): string { if (!text) return ''; return text .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, "'") .replace(/</g, '<') .replace(/>/g, '>') .replace(/ /g, ' ') .trim(); } export interface SEOData { title: string; description: string; excerpt?: string; date?: string; modified?: string; image?: string; } /** * Generate SEO metadata for a WordPress page/post */ export function generateSEOMetadata(data: SEOData): Metadata { const { title, description, excerpt, date, modified, image } = data; // Clean title (max 60 chars for SEO) const cleanTitle = cleanHtmlEntities(title); const seoTitle = cleanTitle.length > 60 ? cleanTitle.substring(0, 57) + '...' : cleanTitle; const fullTitle = `${seoTitle} | Rocky Mountain Vending`; // Clean description (150-160 chars) let seoDescription = description || excerpt || ''; if (seoDescription.length > 160) { seoDescription = seoDescription.substring(0, 157) + '...'; } else if (seoDescription.length < 120) { seoDescription = seoDescription || 'Rocky Mountain Vending provides quality vending machine services in Utah.'; } // Default image const ogImage = image || '/images/rocky-mountain-vending-service-area-926x1024.webp'; const metadata: Metadata = { title: fullTitle, description: seoDescription, openGraph: { title: fullTitle, description: seoDescription, type: 'website', images: [ { url: ogImage, width: 1200, height: 630, alt: cleanTitle, }, ], siteName: 'Rocky Mountain Vending', }, twitter: { card: 'summary_large_image', title: fullTitle, description: seoDescription, images: [ogImage], }, }; // Add dates if available (via openGraph) if (date || modified) { metadata.openGraph = { ...metadata.openGraph, ...(date && { publishedTime: date }), ...(modified && { modifiedTime: modified }), }; } return metadata; } /** * Generate structured data (JSON-LD) for a page */ export function generateStructuredData(data: { title: string; description: string; url: string; datePublished?: string; dateModified?: string; type?: 'Article' | 'WebPage'; }) { const { title, description, url, datePublished, dateModified, type = 'WebPage' } = data; const structuredData: any = { '@context': 'https://schema.org', '@type': type, headline: cleanHtmlEntities(title), description: cleanHtmlEntities(description), url: url, }; if (datePublished) { structuredData.datePublished = datePublished; } if (dateModified) { structuredData.dateModified = dateModified; } if (type === 'Article') { structuredData.author = { '@type': 'Organization', name: 'Rocky Mountain Vending', url: 'https://rockymountainvending.com', }; structuredData.publisher = { '@type': 'Organization', name: 'Rocky Mountain Vending', legalName: 'Rocky Mountain Vending LLC', url: 'https://rockymountainvending.com', logo: { '@type': 'ImageObject', url: 'https://rockymountainvending.com/rmv-logo.png', width: 180, height: 45, }, }; structuredData.mainEntityOfPage = { '@type': 'WebPage', '@id': url, }; } return structuredData; }