Add auto-updating sitemap.xml and robots.txt

Sitemap combines hardcoded static routes with Payload's Pages and
published Posts collections (hourly ISR revalidation), so new CMS
pages/blog posts appear without a code change. Excludes noindex
transactional routes (checkout, cart, bestellbestaetigung,
newsletter-confirmed, konto/*) to avoid Search Console warnings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Eg6h91yngXmSnM51wxXM8
This commit is contained in:
Marco
2026-08-29 21:28:42 +00:00
parent 33f3adb92c
commit 06fee1739d
3 changed files with 121 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
import type { MetadataRoute } from "next";
import { getAllPageSlugs, getAllPostSlugs } from "./lib/payload";
const SITE_URL = "https://einfach-produktiv.mk360.de";
// Every indexable static route in this repo. Deliberately excludes:
// - transactional/session pages already marked `robots: noindex` in their
// own page.tsx (checkout, checkout/verarbeitung, cart, bestellbestaetigung,
// newsletter-confirmed, company-settings-preview, /konto/*) — Google
// explicitly advises against listing noindex URLs in a sitemap.
// - /sticker/[code] and /r/[code]: redirect-only routes with no content of
// their own (see resolveAndTrackRedirect), not pages to index.
// - /email-preview/[type]: internal template-preview tool, not customer-facing.
// - /blog/[slug] and /[slug] (Payload Pages): appended dynamically below.
const STATIC_ROUTES = [
"",
"/blog",
"/shop",
"/newsletter",
"/todo-cards",
"/der-eine",
"/tasse-die-pause",
"/die-sieben",
"/einfach-anfangen",
"/7-tage-klarheits-check",
"/sticker",
"/agb",
"/datenschutz",
"/impressum",
"/versand",
"/widerruf",
];
// New routes only ever need adding in one of two places from now on: a
// plain static page.tsx goes in STATIC_ROUTES above; anything authored
// through Payload (a Pages doc or a blog Post) shows up here automatically
// the next time this regenerates — no code change needed for those.
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const [pages, posts] = await Promise.all([getAllPageSlugs(), getAllPostSlugs()]);
const staticEntries: MetadataRoute.Sitemap = STATIC_ROUTES.map((path) => ({
url: `${SITE_URL}${path}`,
changeFrequency: path === "" ? "daily" : "weekly",
priority: path === "" ? 1 : 0.7,
}));
const pageEntries: MetadataRoute.Sitemap = pages.map(({ slug, updatedAt }) => ({
url: `${SITE_URL}/${slug}`,
lastModified: updatedAt,
changeFrequency: "monthly",
priority: 0.6,
}));
const postEntries: MetadataRoute.Sitemap = posts.map(({ slug, updatedAt }) => ({
url: `${SITE_URL}/blog/${slug}`,
lastModified: updatedAt,
changeFrequency: "monthly",
priority: 0.5,
}));
return [...staticEntries, ...pageEntries, ...postEntries];
}