Files
worldcup/app/sitemap.ts
T
valknar 7fb54683e4 fix: mark sitemap as dynamic to avoid DB query at build time
The sitemap queries the database, which is only reachable at runtime
(not during next build where the 'db' hostname is unavailable).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:25:46 +02:00

46 lines
1.7 KiB
TypeScript

import type { MetadataRoute } from 'next'
export const dynamic = 'force-dynamic'
import { db } from '@/lib/db'
import { tournaments, teams, goals } from '@/lib/db/schema'
import { asc } from 'drizzle-orm'
const BASE = (process.env.NEXT_PUBLIC_SITE_URL ?? 'http://localhost:3000').replace(/\/$/, '')
function slugify(name: string) {
return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
}
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const now = new Date()
const [allTournaments, allTeams, allPlayers] = await Promise.all([
db.select({ year: tournaments.year }).from(tournaments).orderBy(asc(tournaments.year)),
db.select({ name: teams.name }).from(teams).orderBy(asc(teams.name)),
db.selectDistinct({ playerName: goals.playerName }).from(goals),
])
return [
{ url: BASE, lastModified: now, changeFrequency: 'hourly', priority: 1 },
{ url: `${BASE}/groups`, lastModified: now, changeFrequency: 'hourly', priority: 0.9 },
{ url: `${BASE}/history`, changeFrequency: 'monthly', priority: 0.7 },
{ url: `${BASE}/stats`, changeFrequency: 'daily', priority: 0.7 },
...allTournaments.map(t => ({
url: `${BASE}/tournaments/${t.year}`,
changeFrequency: (t.year === 2026 ? 'hourly' : 'monthly') as 'hourly' | 'monthly',
priority: t.year === 2026 ? 0.95 : 0.6,
})),
...allTeams.map(t => ({
url: `${BASE}/teams/${slugify(t.name)}`,
changeFrequency: 'weekly' as const,
priority: 0.5,
})),
...allPlayers.map(p => ({
url: `${BASE}/players/${encodeURIComponent(p.playerName)}`,
changeFrequency: 'monthly' as const,
priority: 0.4,
})),
]
}