Feat: Add a 404 page so unknown URLs stop serving the homepage

Cloudflare Pages falls back to the homepage with a 200 when there's no
404.html, which Google treats as soft 404s. The generated 404.html is
noindex and shows a detective gif from vibegif.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 22:18:53 +00:00
co-authored by Claude Opus 5.5
parent 5a4ff08d11
commit d18ca38882
3 changed files with 28 additions and 3 deletions
+3 -2
View File
@@ -6,7 +6,7 @@ import { marked } from "marked";
import markedKatex from "marked-katex-extension";
import { ARTICLES_GLOB, AUTHOR_PAGES, ROOT, SRC, UNLISTED_PATH } from "./lib/constants.mjs";
import { fixInternalLinks } from "./lib/utils.mjs";
import { renderArticle, renderHome, renderWritePage, renderNewsletterPage, renderUnsubscribePage, renderAuthorPage } from "./lib/renderers.mjs";
import { renderArticle, renderHome, renderWritePage, renderNewsletterPage, renderUnsubscribePage, renderAuthorPage, renderNotFound } from "./lib/renderers.mjs";
import { ensureCleanGenerated, writeDiscoveryFiles, writePage } from "./lib/io.mjs";
marked.use(markedKatex({ throwOnError: false, nonStandard: true }));
@@ -67,6 +67,7 @@ const run = async () => {
await writePage([SRC, "write", "index.html"], renderWritePage());
await writePage([SRC, "newsletter", "index.html"], renderNewsletterPage());
await writePage([SRC, "newsletter", "unsubscribe.html"], renderUnsubscribePage());
await writePage([SRC, "404.html"], renderNotFound());
for (const author of AUTHOR_PAGES) {
await writePage([SRC, "author", author.slug, "index.html"], renderAuthorPage(author));
@@ -79,7 +80,7 @@ const run = async () => {
await writeDiscoveryFiles(listedArticles, AUTHOR_PAGES);
console.log(`Generated ${articles.length} article pages (${listedArticles.length} listed) + home + write + newsletter + unsubscribe + author pages + rss/sitemap/robots.`);
console.log(`Generated ${articles.length} article pages (${listedArticles.length} listed) + home + write + newsletter + unsubscribe + author pages + 404 + rss/sitemap/robots.`);
};
run().catch((err) => {