2026-02-02 20:34:35 +00:00
/**
* Compare Page (SSR)
* Side-by-side comparison of schools with metrics
*/
import { fetchComparison , fetchMetrics } from '@/lib/api' ;
import { ComparisonView } from '@/components/ComparisonView' ;
2026-08-20 22:11:34 +01:00
import { absoluteUrl } from '@/lib/site' ;
2026-02-02 20:34:35 +00:00
import type { Metadata } from 'next' ;
interface ComparePageProps {
searchParams : Promise < {
urns? : string ;
metric? : string ;
} > ;
}
2026-08-20 22:11:34 +01:00
/**
* Indexability depends on the query string, so this cannot be a static export.
*
* Bare /compare is the landing page for the "compare schools" head term and
* stays indexable. /compare?urns=… is an unbounded parameter space — 25,193
* schools make ~317 million pairs — so it goes noindex. It stays `follow` and
* keeps a canonical to the bare path, so the links out to each school page
* still count.
*/
export async function generateMetadata (
{ searchParams } : ComparePageProps ,
) : Promise < Metadata > {
const { urns } = await searchParams ;
const base : Metadata = {
2026-08-21 00:21:08 +01:00
// Deliberately not the homepage's phrase. Two pages chasing "compare
// schools" is how a site competes with itself; this one takes the tool
// phrasing instead.
2026-09-30 11:56:54 +01:00
title : 'School Comparison Tool: Primary and Secondary Schools | schoolcompare' ,
2026-08-20 22:11:34 +01:00
description :
2026-09-30 11:56:54 +01:00
'Put up to five primary and five secondary schools in England in one table: SATs and GCSE results against the England average, Ofsted grades, and the distance places were offered.' ,
2026-08-20 22:11:34 +01:00
keywords :
'school comparison, compare schools, Ofsted comparison, school admissions, KS2 comparison, primary school performance' ,
alternates : { canonical : absoluteUrl ( '/compare' ) },
};
if ( ! urns ) return base ;
return { ... base , robots : { index : false , follow : true } };
}
2026-02-02 20:34:35 +00:00
2026-06-02 13:46:45 +01:00
// Dynamic via searchParams; remove force-dynamic so internal data fetches
// can still use Next.js's per-call revalidate cache.
2026-02-02 20:34:35 +00:00
export default async function ComparePage ({ searchParams } : ComparePageProps ) {
const { urns : urnsParam , metric : metricParam } = await searchParams ;
const urns = urnsParam ? . split ( ',' ). map ( Number ). filter ( Boolean ) || [];
const selectedMetric = metricParam || 'rwm_expected_pct' ;
2026-02-02 21:28:50 +00:00
try {
2026-07-14 13:06:52 +01:00
// Fetch comparison + metrics in parallel — they are independent.
const [ comparisonResponse , metricsResponse ] = await Promise . all ([
urns . length > 0
? fetchComparison ( urnsParam ! ). catch (( error ) => {
console . error ( 'Failed to fetch comparison:' , error );
return null ;
})
: Promise . resolve ( null ),
fetchMetrics (),
]);
2026-02-02 21:28:50 +00:00
2026-02-02 22:00:07 +00:00
const metricsArray = metricsResponse ? . metrics || [];
2026-02-02 21:28:50 +00:00
return (
< ComparisonView
2026-07-14 13:06:52 +01:00
initialData = { comparisonResponse ? . comparison ?? null }
initialNationalAverages = { comparisonResponse ? . national_averages }
initialBenchmarks = { comparisonResponse ? . benchmarks }
2026-02-02 21:28:50 +00:00
initialUrns = { urns }
metrics = { metricsArray }
selectedMetric = { selectedMetric }
/>
);
} catch ( error ) {
console . error ( 'Error fetching data for compare page:' , error );
// Return error state with empty metrics
return (
< ComparisonView
initialData = { null }
initialUrns = { urns }
metrics = {[]}
selectedMetric = { selectedMetric }
/>
);
2026-02-02 20:34:35 +00:00
}
}