Skip to content

Commit 4070fdc

Browse files
committed
Add generateStaticParams to comparison routes to fix 404 errors
1 parent 2339aa7 commit 4070fdc

File tree

1 file changed

+130
-0
lines changed
  • src/app/comparisons/[tool1]/vs/[tool2]

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { Suspense } from 'react'
2+
import { notFound } from 'next/navigation'
3+
import { Metadata } from 'next'
4+
import { getToolBySlug, getAllTools } from '@/actions/tool-actions'
5+
import ComparisonPageLayout from '@/components/ComparisonPageLayout'
6+
import { generateComparisonProse } from '@/utils/comparison-helpers'
7+
import { createMetadata } from '@/utils/createMetadata'
8+
import { ComparisonPageSkeleton } from '@/components/comparison-page-skeleton'
9+
10+
interface PageProps {
11+
params: Promise<{
12+
tool1: string
13+
tool2: string
14+
}>
15+
}
16+
17+
// Generate static params for all possible tool combinations
18+
export async function generateStaticParams() {
19+
try {
20+
const tools = await getAllTools()
21+
const params = []
22+
23+
// Generate all possible combinations of tools
24+
for (let i = 0; i < tools.length; i++) {
25+
for (let j = i + 1; j < tools.length; j++) {
26+
const tool1 = tools[i]
27+
const tool2 = tools[j]
28+
29+
// Create slug from tool name
30+
const createSlug = (name: string) => {
31+
return name
32+
.toLowerCase()
33+
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters except spaces and hyphens
34+
.replace(/\s+/g, '-') // Replace spaces with hyphens
35+
.replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
36+
.replace(/^-|-$/g, '') // Remove leading/trailing hyphens
37+
}
38+
39+
const tool1Slug = createSlug(tool1.name)
40+
const tool2Slug = createSlug(tool2.name)
41+
42+
// Add both combinations (tool1 vs tool2 and tool2 vs tool1)
43+
params.push({
44+
tool1: tool1Slug,
45+
tool2: tool2Slug
46+
})
47+
params.push({
48+
tool1: tool2Slug,
49+
tool2: tool1Slug
50+
})
51+
}
52+
}
53+
54+
console.log(`Generated ${params.length} static params for comparison routes`)
55+
return params
56+
} catch (error) {
57+
console.error('Error generating static params for comparisons:', error)
58+
return []
59+
}
60+
}
61+
62+
// Generate metadata for SEO
63+
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
64+
const { tool1: tool1Slug, tool2: tool2Slug } = await params
65+
66+
try {
67+
const [tool1, tool2] = await Promise.all([
68+
getToolBySlug(tool1Slug),
69+
getToolBySlug(tool2Slug)
70+
])
71+
72+
if (!tool1 || !tool2) {
73+
return createMetadata({
74+
title: "Comparison Not Found",
75+
description: "The requested tool comparison could not be found."
76+
})
77+
}
78+
79+
return createMetadata({
80+
title: `${tool1.name} vs ${tool2.name}`,
81+
description: `Compare ${tool1.name} and ${tool2.name} - features, pricing, pros and cons. Find the best tool for your development needs.`,
82+
slug: `${tool1Slug}-vs-${tool2Slug}`
83+
})
84+
} catch (error) {
85+
console.error('Error generating metadata:', error)
86+
return createMetadata({
87+
title: "Comparison Error",
88+
description: "Error loading comparison data."
89+
})
90+
}
91+
}
92+
93+
async function ComparisonContent({ tool1Slug, tool2Slug }: { tool1Slug: string, tool2Slug: string }) {
94+
try {
95+
const [tool1, tool2] = await Promise.all([
96+
getToolBySlug(tool1Slug),
97+
getToolBySlug(tool2Slug)
98+
])
99+
100+
if (!tool1 || !tool2) {
101+
notFound()
102+
}
103+
104+
const proseParagraphs = generateComparisonProse(tool1, tool2)
105+
106+
return (
107+
<ComparisonPageLayout
108+
tool1={tool1}
109+
tool2={tool2}
110+
proseParagraphs={proseParagraphs}
111+
/>
112+
)
113+
} catch (error) {
114+
console.error('Error loading comparison:', error)
115+
throw error
116+
}
117+
}
118+
119+
export default async function ComparisonPage({ params }: PageProps) {
120+
const { tool1: tool1Slug, tool2: tool2Slug } = await params
121+
122+
return (
123+
<Suspense fallback={<ComparisonPageSkeleton />}>
124+
<ComparisonContent tool1Slug={tool1Slug} tool2Slug={tool2Slug} />
125+
</Suspense>
126+
)
127+
}
128+
129+
// Enable ISR with 1 hour revalidation
130+
export const revalidate = 3600

0 commit comments

Comments
 (0)