feat: add branded 404 page

This commit is contained in:
2026-08-30 13:49:35 -03:00
parent 48f05bcf8a
commit a3859f1efc
7 changed files with 256 additions and 2 deletions
+29 -2
View File
@@ -11,7 +11,7 @@ import { seedDemoMemes } from './src/seed.js';
import { moderateImage } from './src/moderation.js';
import { createUploadLimiter } from './src/uploadLimits.js';
import { createIpRateLimiter } from './src/rateLimits.js';
import { feedJson, llmsTxt, manifest, noIndex, publicBaseUrl, renderIndex, robotsTxt, sitemapXml } from './src/seo.js';
import { feedJson, llmsTxt, manifest, noIndex, publicBaseUrl, renderIndex, renderNotFound, robotsTxt, sitemapXml } from './src/seo.js';
await loadDotEnv();
@@ -36,6 +36,7 @@ const DISCOVERY_ROUTES = new Set([
]);
const ADMIN_TOKEN = process.env.ADMIN_TOKEN || crypto.randomBytes(24).toString('hex');
const indexTemplate = await fs.readFile('./public/index.html', 'utf8');
const notFoundTemplate = await fs.readFile('./public/404.html', 'utf8');
const openApiSpec = JSON.parse(await fs.readFile('./openapi.json', 'utf8'));
const memeApiSkillTemplate = await fs.readFile('./meme-api.skill.md', 'utf8');
@@ -90,7 +91,9 @@ const server = http.createServer(async (req, res) => {
const memePageMatch = url.pathname.match(/^\/meme\/([a-f0-9]{64})\/?$/);
if (req.method === 'GET' && memePageMatch) {
const meme = store.get(memePageMatch[1]);
if (!meme || meme.status !== 'approved') return sendText(res, 404, 'Not found');
if (!meme || meme.status !== 'approved') {
return sendNotFoundPage(res, { baseUrl, pathname: url.pathname });
}
const nonce = crypto.randomBytes(16).toString('base64');
withSecurityHeaders(res, { scriptNonce: nonce });
return sendHtml(res, 200, renderIndex({
@@ -292,6 +295,9 @@ const server = http.createServer(async (req, res) => {
return sendJson(res, 200, { ok: true });
}
if (isBrowserPageRequest(req, url)) {
return sendNotFoundPage(res, { baseUrl, pathname: url.pathname });
}
return sendText(res, 404, 'Not found');
} catch (error) {
const status = error.statusCode || 500;
@@ -323,6 +329,27 @@ function isDiscoveryRoute(req, url) {
return DISCOVERY_ROUTES.has(url.pathname);
}
function isBrowserPageRequest(req, url) {
if (req.method !== 'GET') return false;
return ![
'/api',
'/assets',
'/media',
'/download',
'/admin',
'/admin-media'
].some((prefix) => url.pathname === prefix || url.pathname.startsWith(`${prefix}/`));
}
function sendNotFoundPage(res, { baseUrl, pathname }) {
noIndex(res);
return sendHtml(res, 404, renderNotFound({
template: notFoundTemplate,
baseUrl,
pathname
}));
}
async function loadDotEnv() {
let content = '';
try {