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:
@@ -0,0 +1,42 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user