Skip to content

Commit 5405177

Browse files
ralyodioclaude
andcommitted
feat: add dynamic sitemap.xml and robots.txt
sitemap.ts generates URLs for all static pages, stores, and coupons. robots.ts allows all crawlers, blocks /api/, points to sitemap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 22d29cf commit 5405177

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

apps/web/app/robots.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { MetadataRoute } from 'next';
2+
3+
export default function robots(): MetadataRoute.Robots {
4+
return {
5+
rules: { userAgent: '*', allow: '/', disallow: '/api/' },
6+
sitemap: 'https://c0upons.com/sitemap.xml',
7+
};
8+
}

apps/web/app/sitemap.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import type { MetadataRoute } from 'next';
2+
import { getDb } from '@/lib/db';
3+
4+
const BASE = 'https://c0upons.com';
5+
6+
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
7+
const staticRoutes: MetadataRoute.Sitemap = [
8+
{ url: BASE, changeFrequency: 'daily', priority: 1 },
9+
{ url: `${BASE}/stores`, changeFrequency: 'daily', priority: 0.9 },
10+
{ url: `${BASE}/submit`, changeFrequency: 'monthly', priority: 0.7 },
11+
{ url: `${BASE}/docs`, changeFrequency: 'monthly', priority: 0.6 },
12+
{ url: `${BASE}/search`, changeFrequency: 'monthly', priority: 0.5 },
13+
];
14+
15+
try {
16+
const db = getDb();
17+
18+
const stores = await db.sql`SELECT slug, created_at FROM stores ORDER BY created_at DESC`;
19+
const coupons = await db.sql`SELECT id, created_at FROM coupons ORDER BY created_at DESC`;
20+
21+
const storeRoutes: MetadataRoute.Sitemap = stores.map((s: { slug: string; created_at: string }) => ({
22+
url: `${BASE}/stores/${s.slug}`,
23+
lastModified: s.created_at ? new Date(s.created_at) : undefined,
24+
changeFrequency: 'weekly',
25+
priority: 0.8,
26+
}));
27+
28+
const couponRoutes: MetadataRoute.Sitemap = coupons.map((c: { id: number; created_at: string }) => ({
29+
url: `${BASE}/coupons/${c.id}`,
30+
lastModified: c.created_at ? new Date(c.created_at) : undefined,
31+
changeFrequency: 'weekly',
32+
priority: 0.6,
33+
}));
34+
35+
return [...staticRoutes, ...storeRoutes, ...couponRoutes];
36+
} catch {
37+
return staticRoutes;
38+
}
39+
}

0 commit comments

Comments
 (0)