Files
community-rule/lib/publicSitemap.ts
T
adilalloandCursor b2b272d2cc Give each route its own title and canonical, and add robots.txt plus a sitemap.
The root layout was stamping the homepage title and production root onto every page. Routes now supply a page segment through one em-dash template, canonicals follow the request path, and non-production hosts disallow crawlers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 16:45:19 -06:00

43 lines
1.1 KiB
TypeScript

import type { MetadataRoute } from "next";
import { getAllBlogPosts } from "./content";
import { sitemapUrl } from "./siteMetadata";
import { USE_CASE_DETAIL_SLUGS } from "./useCaseSyntheticPost";
const STATIC_PUBLIC_PATHS = [
"/",
"/about",
"/learn",
"/templates",
"/blog",
"/use-cases",
"/how-it-works",
"/privacy",
"/terms",
"/cookies",
] as const;
/**
* Public marketing URLs for `/sitemap.xml`. Omits signed-in product routes
* (`/create`, `/login`, `/profile`), admin, and `/rules/[id]` (those ids are
* not known without the database).
*/
export function buildPublicSitemap(): MetadataRoute.Sitemap {
const entries: MetadataRoute.Sitemap = STATIC_PUBLIC_PATHS.map((path) => ({
url: sitemapUrl(path),
}));
for (const post of getAllBlogPosts()) {
entries.push({
url: sitemapUrl(`/blog/${post.slug}`),
lastModified: post.lastModified,
});
}
for (const slug of USE_CASE_DETAIL_SLUGS) {
entries.push({ url: sitemapUrl(`/use-cases/${slug}`) });
entries.push({ url: sitemapUrl(`/use-cases/${slug}/rule`) });
}
return entries;
}