import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; import { after } from 'next/server'; import { ComparisonPage } from '@/components/marketing/comparison-page'; import { readPageVisitor, recordVisitorEvent } from '@/lib/analytics/visitor'; import { auth } from '@/lib/auth'; import { comparisonPages, getComparisonPage } from '@/lib/marketing/comparison-pages'; import { buildComparisonJsonLd, buildComparisonMetadata } from '@/lib/marketing/metadata'; interface MarketingSlugPageProps { params: Promise<{ slug: string }>; } export function generateStaticParams() { return comparisonPages.map((page) => ({ slug: page.slug })); } export async function generateMetadata({ params }: MarketingSlugPageProps): Promise { const { slug } = await params; const page = getComparisonPage(slug); if (!page) { return {}; } return buildComparisonMetadata({ title: page.title, description: page.metaDescription, path: `/${page.slug}`, keywords: page.keywords, }); } export default async function MarketingSlugPage({ params }: MarketingSlugPageProps) { const { slug } = await params; const page = getComparisonPage(slug); if (!page) { notFound(); } const session = await auth(); const isLoggedIn = Boolean(session?.user); // A comparison page is a landing page: for most of these visitors it is the // first thing they see, so it belongs in the same visitor count as `/`. if (!isLoggedIn) { const visitor = await readPageVisitor(); after(() => recordVisitorEvent('LANDING_VIEW', visitor)); } const structuredData = buildComparisonJsonLd({ title: page.title, description: page.metaDescription, path: `/${page.slug}`, faq: page.faq, }); return ( <> {/* One script per object: single-object payloads with a top-level @context survive naive JSON-LD consumers that choke on arrays. */} {structuredData.map((data, index) => (