Files
Spanglish/frontend/src/app/sitemap.ts

112 lines
2.9 KiB
TypeScript

import { MetadataRoute } from 'next';
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://spanglish.com.py';
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
interface SitemapEvent {
id: string;
status: string;
startDatetime: string;
updatedAt: string;
}
/**
* Fetch all indexable events: published, completed, and cancelled.
* Sold-out / past events stay in the index (marked as expired, not removed).
* Only draft and archived events are excluded.
*/
async function getIndexableEvents(): Promise<SitemapEvent[]> {
try {
const [publishedRes, completedRes] = await Promise.all([
fetch(`${apiUrl}/api/events?status=published`, {
next: { tags: ['events-sitemap'] },
}),
fetch(`${apiUrl}/api/events?status=completed`, {
next: { tags: ['events-sitemap'] },
}),
]);
const published = publishedRes.ok
? ((await publishedRes.json()).events as SitemapEvent[]) || []
: [];
const completed = completedRes.ok
? ((await completedRes.json()).events as SitemapEvent[]) || []
: [];
return [...published, ...completed];
} catch {
return [];
}
}
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const events = await getIndexableEvents();
const now = new Date();
// Static pages
const staticPages: MetadataRoute.Sitemap = [
{
url: siteUrl,
lastModified: now,
changeFrequency: 'weekly',
priority: 1,
},
{
url: `${siteUrl}/events`,
lastModified: now,
changeFrequency: 'daily',
priority: 0.9,
},
{
url: `${siteUrl}/community`,
lastModified: now,
changeFrequency: 'monthly',
priority: 0.7,
},
{
url: `${siteUrl}/contact`,
lastModified: now,
changeFrequency: 'monthly',
priority: 0.6,
},
{
url: `${siteUrl}/faq`,
lastModified: now,
changeFrequency: 'monthly',
priority: 0.6,
},
// Legal pages
{
url: `${siteUrl}/legal/terms-policy`,
lastModified: now,
changeFrequency: 'yearly',
priority: 0.3,
},
{
url: `${siteUrl}/legal/privacy-policy`,
lastModified: now,
changeFrequency: 'yearly',
priority: 0.3,
},
{
url: `${siteUrl}/legal/refund-cancelation-policy`,
lastModified: now,
changeFrequency: 'yearly',
priority: 0.3,
},
];
// Dynamic event pages — upcoming events get higher priority
const eventPages: MetadataRoute.Sitemap = events.map((event) => {
const isUpcoming = new Date(event.startDatetime) > now;
return {
url: `${siteUrl}/events/${event.id}`,
lastModified: new Date(event.updatedAt),
changeFrequency: isUpcoming ? ('weekly' as const) : ('monthly' as const),
priority: isUpcoming ? 0.8 : 0.5,
};
});
return [...staticPages, ...eventPages];
}