137 lines
4.6 KiB
TypeScript
137 lines
4.6 KiB
TypeScript
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<MetadataRoute.Sitemap> {
|
|
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();
|
|
}
|
|
}
|
|
|