import { MetadataRoute } from 'next'; import { PrismaClient } from '@prisma/client'; import { getLocalizedValue } from '@/lib/i18n'; import { config } from '@/lib/config'; const prisma = new PrismaClient(); export default async function sitemap(): Promise { const baseUrl = process.env.NEXT_PUBLIC_DOMAIN || config.domain; const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http'; const siteUrl = `${protocol}://${baseUrl}`; const now = new Date().toISOString(); // Static pages const staticPages: MetadataRoute.Sitemap = [ { url: `${siteUrl}/en`, lastModified: now, changeFrequency: 'daily', priority: 1.0, alternates: { languages: { 'de': `${siteUrl}/de`, 'en': `${siteUrl}/en`, 'x-default': `${siteUrl}/en`, }, }, }, { url: `${siteUrl}/de`, lastModified: now, changeFrequency: 'monthly', priority: 0.8, alternates: { languages: { 'de': `${siteUrl}/de`, 'en': `${siteUrl}/en`, 'x-default': `${siteUrl}/en`, }, }, }, { url: `${siteUrl}/en/about`, lastModified: now, changeFrequency: 'monthly', priority: 0.7, alternates: { languages: { 'de': `${siteUrl}/de/about`, 'en': `${siteUrl}/en/about`, 'x-default': `${siteUrl}/en/about`, }, }, }, { url: `${siteUrl}/de/about`, lastModified: now, changeFrequency: 'monthly', priority: 0.7, alternates: { languages: { 'de': `${siteUrl}/de/about`, 'en': `${siteUrl}/en/about`, 'x-default': `${siteUrl}/en/about`, }, }, }, ]; // Dynamic genre pages try { // Während des Docker-Builds wird häufig eine temporäre SQLite-DB (file:./dev.db) // ohne migrierte Tabellen verwendet. In diesem Fall überspringen wir die // Datenbankabfrage und liefern nur die statischen Seiten, um Build-Fehler zu vermeiden. const dbUrl = process.env.DATABASE_URL; if (dbUrl && dbUrl.startsWith('file:./')) { return staticPages; } const genres = await prisma.genre.findMany({ where: { active: true }, }); const genrePages: MetadataRoute.Sitemap = []; for (const genre of genres) { const genreNameEn = getLocalizedValue(genre.name, 'en'); const genreNameDe = getLocalizedValue(genre.name, 'de'); // Only add if genre name is valid if (genreNameEn && genreNameDe) { const encodedEn = encodeURIComponent(genreNameEn); const encodedDe = encodeURIComponent(genreNameDe); genrePages.push( { url: `${siteUrl}/en/${encodedEn}`, lastModified: now, changeFrequency: 'daily', priority: 0.9, alternates: { languages: { 'de': `${siteUrl}/de/${encodedDe}`, 'en': `${siteUrl}/en/${encodedEn}`, 'x-default': `${siteUrl}/en/${encodedEn}`, }, }, }, { url: `${siteUrl}/de/${encodedDe}`, lastModified: now, changeFrequency: 'daily', priority: 0.9, alternates: { languages: { 'de': `${siteUrl}/de/${encodedDe}`, 'en': `${siteUrl}/en/${encodedEn}`, 'x-default': `${siteUrl}/en/${encodedEn}`, }, }, } ); } } return [...staticPages, ...genrePages]; } catch (error) { console.error('Error generating sitemap:', error); // Return static pages only if database query fails return staticPages; } finally { await prisma.$disconnect(); } }