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 - z 0 - 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