← back to Open Seo
badseo/src/server/badseo.ts
97 lines
import {
fixturePaths,
sitemapFixtures,
allFixtures,
} from "../fixtures/registry";
import { TRAILING_SLASH_CANONICAL } from "../fixtures/redirects";
import type { Fixture, FixtureContext } from "../fixtures/types";
import { redirect, renderShell } from "../lib";
const routeTable = new Map<string, Fixture>();
for (const fixture of allFixtures) {
for (const path of fixturePaths(fixture)) routeTable.set(path, fixture);
}
function normalizePath(pathname: string): string {
if (pathname.length > 1 && pathname.endsWith("/")) {
return pathname.slice(0, -1);
}
return pathname;
}
function requestOrigin(request: Request, url: URL): string {
const host = request.headers.get("host") ?? url.host;
return `${url.protocol}//${host}`;
}
export async function handleFixtureRequest(
request: Request,
): Promise<Response> {
const url = new URL(request.url);
const path = normalizePath(url.pathname);
if (url.pathname === TRAILING_SLASH_CANONICAL) {
return redirect(`${TRAILING_SLASH_CANONICAL}/`, 301);
}
const fixture = routeTable.get(path);
if (fixture) {
const context: FixtureContext = {
origin: requestOrigin(request, url),
request,
path,
};
return fixture.handler(context);
}
return new Response(
renderShell({
title: "404, not found | badseo.dev",
metaDescription: "That URL is not one of the pages on this site.",
bodyHtml: `<h1>404, not found</h1>
<p class="lede">This URL is not one of the broken pages on the site. It is just missing.</p>
<p>Go back to the <a href="/#issues">examples</a> to see the pages that break on purpose.</p>`,
}),
{
status: 404,
headers: {
"content-type": "text/html; charset=utf-8",
"cache-control": "no-store",
},
},
);
}
export function robotsResponse(request: Request): Response {
const url = new URL(request.url);
const origin = requestOrigin(request, url);
return new Response(
`# badseo.dev is broken on purpose, but it lets crawlers in.
User-agent: *
Allow: /
Sitemap: ${origin}/sitemap.xml
`,
{ headers: { "content-type": "text/plain; charset=utf-8" } },
);
}
export function sitemapResponse(request: Request): Response {
const url = new URL(request.url);
const origin = requestOrigin(request, url);
const paths = new Set<string>(["/", "/privacy"]);
for (const fixture of sitemapFixtures) {
for (const path of fixturePaths(fixture)) paths.add(path);
}
const urls = [...paths]
.map((path) => ` <url><loc>${origin}${path}</loc></url>`)
.join("\n");
const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls}
</urlset>`;
return new Response(body, {
headers: { "content-type": "application/xml; charset=utf-8" },
});
}