feat: initialize landing page with dynamic competitor comparison routes and structured SEO metadata
This commit is contained in:
70
greenlns-landing/app/vs/[competitor]/page.tsx
Normal file
70
greenlns-landing/app/vs/[competitor]/page.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { notFound } from 'next/navigation'
|
||||
import ComparisonPage from '@/components/ComparisonPage'
|
||||
import { competitorOrder, getCompetitorBySlug, getPeerCompetitors } from '@/lib/competitors'
|
||||
import { siteConfig } from '@/lib/site'
|
||||
|
||||
type ComparisonRouteProps = {
|
||||
params: Promise<{ competitor: string }>
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
return competitorOrder.map((competitor) => ({ competitor }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: ComparisonRouteProps): Promise<Metadata> {
|
||||
const { competitor } = await params
|
||||
const profile = getCompetitorBySlug(competitor)
|
||||
|
||||
if (!profile) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const path = `/vs/${profile.slug}`
|
||||
|
||||
return {
|
||||
title: profile.metaTitle,
|
||||
description: profile.metaDescription,
|
||||
alternates: {
|
||||
canonical: path,
|
||||
},
|
||||
keywords: [
|
||||
`${siteConfig.name.toLowerCase()} vs ${profile.name.toLowerCase()}`,
|
||||
`${profile.name.toLowerCase()} alternative`,
|
||||
'plant emergency app',
|
||||
'plant care app comparison',
|
||||
'plant diagnosis app',
|
||||
],
|
||||
openGraph: {
|
||||
title: profile.metaTitle,
|
||||
description: profile.metaDescription,
|
||||
url: `${siteConfig.domain}${path}`,
|
||||
type: 'website',
|
||||
images: [
|
||||
{
|
||||
url: '/og-image.png',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: `${profile.metaTitle} comparison page`,
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: profile.metaTitle,
|
||||
description: profile.metaDescription,
|
||||
images: ['/og-image.png'],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function ComparisonRoute({ params }: ComparisonRouteProps) {
|
||||
const { competitor } = await params
|
||||
const profile = getCompetitorBySlug(competitor)
|
||||
|
||||
if (!profile) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
return <ComparisonPage competitor={profile} peers={getPeerCompetitors(profile.slug)} />
|
||||
}
|
||||
Reference in New Issue
Block a user