← back to Nineoh Guide
apps/web/app/sitemap.ts
55 lines
import type { MetadataRoute } from "next";
import { pool } from "@/lib/db";
import { SITE_URL, episodePath, castPath, slugify } from "@nineoh/core";
import { GAMES } from "@/lib/games";
export const dynamic = "force-dynamic";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const urls: MetadataRoute.Sitemap = [
"",
"/show",
"/episodes",
"/cast",
"/characters",
"/news",
"/games",
"/community",
"/search",
"/legal/disclaimer",
"/legal/dmca",
"/legal/privacy",
].map((p) => ({ url: `${SITE_URL}${p}`, changeFrequency: "weekly", priority: p === "" ? 1 : 0.6 }));
for (const g of GAMES) {
urls.push({ url: `${SITE_URL}/games/${g.file}`, changeFrequency: "monthly", priority: 0.5 });
}
try {
const eps = await pool.query(
`select season_number, episode_number from episodes order by season_number, episode_number`
);
for (const e of eps.rows) {
urls.push({
url: `${SITE_URL}${episodePath(e.season_number, e.episode_number)}`,
changeFrequency: "monthly",
priority: 0.7,
});
}
const cast = await pool.query(`select name from cast_people order by name`);
for (const c of cast.rows) {
urls.push({ url: `${SITE_URL}${castPath(c.name)}`, changeFrequency: "monthly", priority: 0.5 });
}
const chars = await pool.query(
`select name from characters where description_original is not null order by name`
);
for (const c of chars.rows) {
urls.push({ url: `${SITE_URL}/characters/${slugify(c.name)}`, changeFrequency: "monthly", priority: 0.5 });
}
} catch {
/* DB unreachable at build — static routes still returned */
}
return urls;
}