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>
This commit is contained in:
adilallo
2026-09-09 16:45:19 -06:00
co-authored by Cursor
parent e4e61c0c9b
commit b2b272d2cc
32 changed files with 573 additions and 72 deletions
+39
View File
@@ -0,0 +1,39 @@
import { describe, expect, it } from "vitest";
import { getAllBlogPosts } from "../../lib/content";
import { buildPublicSitemap } from "../../lib/publicSitemap";
import { PRODUCTION_SITE_ORIGIN, sitemapUrl } from "../../lib/siteMetadata";
import { USE_CASE_DETAIL_SLUGS } from "../../lib/useCaseSyntheticPost";
describe("buildPublicSitemap", () => {
it("lists public marketing routes, blog posts, and use cases", () => {
const urls = buildPublicSitemap().map((entry) => entry.url);
expect(urls).toContain(PRODUCTION_SITE_ORIGIN);
expect(urls).toContain(sitemapUrl("/about"));
expect(urls).toContain(sitemapUrl("/learn"));
expect(urls).toContain(sitemapUrl("/templates"));
expect(urls).toContain(sitemapUrl("/blog"));
expect(urls).toContain(sitemapUrl("/use-cases"));
expect(urls).toContain(sitemapUrl("/how-it-works"));
expect(urls).toContain(sitemapUrl("/privacy"));
expect(urls).toContain(sitemapUrl("/terms"));
expect(urls).toContain(sitemapUrl("/cookies"));
for (const post of getAllBlogPosts()) {
expect(urls).toContain(sitemapUrl(`/blog/${post.slug}`));
}
for (const slug of USE_CASE_DETAIL_SLUGS) {
expect(urls).toContain(sitemapUrl(`/use-cases/${slug}`));
expect(urls).toContain(sitemapUrl(`/use-cases/${slug}/rule`));
}
});
it("omits signed-in, admin, and API routes", () => {
const urls = buildPublicSitemap().map((entry) => entry.url);
expect(urls.some((url) => url.includes("/login"))).toBe(false);
expect(urls.some((url) => url.includes("/profile"))).toBe(false);
expect(urls.some((url) => url.includes("/create"))).toBe(false);
expect(urls.some((url) => url.includes("/monitor"))).toBe(false);
expect(urls.some((url) => url.includes("/api/"))).toBe(false);
});
});