Files
anouma/scripts/seo-check.ts
T

71 lines
2.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Optional, dev-only SEO sanity check - NOT part of the build or deploy
* pipeline, never blocks production. Run manually:
*
* npm run seo:check
*
* Only ever warns; exits 0 regardless of findings (a content gap here isn't
* a broken deploy).
*/
import { getPayload } from "payload";
import config from "../payload.config";
let warnings = 0;
function warn(message: string) {
warnings++;
console.warn(` ⚠ ${message}`);
}
async function checkCollection(
payload: Awaited<ReturnType<typeof getPayload>>,
collection: "offers" | "events" | "posts",
label: string,
) {
console.log(`${label}:`);
const { docs } = await payload.find({ collection, limit: 500, depth: 0 });
const slugCounts = new Map<string, number>();
for (const doc of docs as { slug?: string | null; title?: string }[]) {
if (doc.slug) slugCounts.set(doc.slug, (slugCounts.get(doc.slug) ?? 0) + 1);
}
for (const [slug, count] of slugCounts) {
if (count > 1) warn(`Slug „${slug}“ kommt ${count}× vor.`);
}
for (const doc of docs as { slug?: string | null; title?: string; seo?: { description?: string | null } | null }[]) {
if (!doc.title?.trim()) warn(`Dokument ohne Titel (slug: ${doc.slug ?? "-"}).`);
if (!doc.slug?.trim()) warn(`Dokument ohne Slug: „${doc.title ?? "-"}“.`);
}
if (docs.length === 0) console.log(" (keine Einträge)");
}
async function checkMedia(payload: Awaited<ReturnType<typeof getPayload>>) {
console.log("Medien (Alt-Texte):");
const { docs } = await payload.find({ collection: "media", limit: 1000, depth: 0 });
const missingAlt = (docs as { alt?: string; filename?: string }[]).filter((doc) => !doc.alt?.trim());
if (missingAlt.length === 0) {
console.log(" Alle Bilder haben einen Alt-Text.");
} else {
for (const doc of missingAlt) warn(`Bild ohne Alt-Text: ${doc.filename ?? "unbekannt"}`);
}
}
async function run() {
const payload = await getPayload({ config });
await checkCollection(payload, "offers", "Angebote");
await checkCollection(payload, "events", "Termine");
await checkCollection(payload, "posts", "Aktuelles");
await checkMedia(payload);
console.log(`\n${warnings === 0 ? "Keine Auffälligkeiten gefunden." : `${warnings} Hinweis(e) gefunden - siehe oben.`}`);
process.exit(0);
}
run().catch((err) => {
console.error(err);
process.exit(0);
});