import type { Metadata } from "next"; import { siteConfig } from "@/data/site-content"; type PageMetadataInput = { title: string; description: string; path: string; image?: string; }; type FaqEntry = { question: string; answer: string; }; type ItemListEntry = { name: string; path?: string; }; export function buildMetadataBase() { const rawUrl = process.env.NEXT_PUBLIC_SITE_URL || siteConfig.siteUrl; return new URL(rawUrl.endsWith("/") ? rawUrl : `${rawUrl}/`); } export function buildAbsoluteUrl(path: string) { return new URL(path, buildMetadataBase()).toString(); } export function buildPageMetadata({ title, description, path, image = siteConfig.defaultOgImage, }: PageMetadataInput): Metadata { return { title, description, alternates: { canonical: path, }, openGraph: { title, description, url: path, images: [ { url: image, alt: title, }, ], }, twitter: { card: "summary_large_image", title, description, images: [image], }, }; } export function websiteSchema() { return { "@type": "WebSite", name: siteConfig.name, url: buildAbsoluteUrl("/"), }; } export function businessSchema() { return { "@type": "LocalBusiness", name: siteConfig.name, url: buildAbsoluteUrl("/"), description: siteConfig.description, logo: buildAbsoluteUrl(siteConfig.brand.primaryLogo), image: buildAbsoluteUrl(siteConfig.defaultOgImage), telephone: siteConfig.phoneDisplay, address: { "@type": "PostalAddress", streetAddress: siteConfig.address.street, addressLocality: "Corpus Christi", addressRegion: "TX", postalCode: "78405", addressCountry: "US", }, sameAs: siteConfig.socials.map((social) => social.href), contactPoint: [ { "@type": "ContactPoint", telephone: siteConfig.phoneDisplay, contactType: "customer service", areaServed: "Corpus Christi, TX", }, ], openingHoursSpecification: [ { "@type": "OpeningHoursSpecification", dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], opens: "08:00", closes: "17:00", }, ], }; } export function localBusinessSchema() { return { "@context": "https://schema.org", ...businessSchema(), }; } export function breadcrumbSchema(items: { name: string; path: string }[]) { return { "@context": "https://schema.org", "@type": "BreadcrumbList", itemListElement: items.map((item, index) => ({ "@type": "ListItem", position: index + 1, name: item.name, item: buildAbsoluteUrl(item.path), })), }; } export function faqPageSchema(items: FaqEntry[]) { return { "@context": "https://schema.org", "@type": "FAQPage", mainEntity: items.map((item) => ({ "@type": "Question", name: item.question, acceptedAnswer: { "@type": "Answer", text: item.answer, }, })), }; } export function itemListSchema({ name, path, items, }: { name: string; path: string; items: ItemListEntry[]; }) { return { "@context": "https://schema.org", "@type": "ItemList", name, url: buildAbsoluteUrl(path), numberOfItems: items.length, itemListOrder: "https://schema.org/ItemListOrderAscending", itemListElement: items.map((item, index) => ({ "@type": "ListItem", position: index + 1, name: item.name, url: item.path ? buildAbsoluteUrl(item.path) : undefined, })), }; }