app/routes/robots.ts
44 lines and 2 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| loader | 15 to 50 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| block | 33 to 34 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
Imports
It imports app/lib/context.ts, app/lib/seo.ts, app/lib/worker-preview.ts. No module of this repo imports it.
Source
import { getEnv } from "~/lib/context";
import { HOURLY_CACHE_CONTROL, SITE_ORIGIN } from "~/lib/seo";
import { isWorkerPreview } from "~/lib/worker-preview";
import type { Route } from "./+types/robots";
const AI_AGENTS = [
"GPTBot",
"OAI-SearchBot",
"ChatGPT-User",
"ClaudeBot",
"PerplexityBot",
"Google-Extended",
];
export function loader({ context }: Route.LoaderArgs) {
const origin = SITE_ORIGIN;
// A Worker Preview is a PR's draft of the site: nothing on it is for crawling. The gateway's
// X-Robots-Tag: noindex is the real control; this is the advisory half.
if (isWorkerPreview(getEnv(context))) {
return new Response("User-agent: *\nDisallow: /\n", {
headers: {
"content-type": "text/plain; charset=utf-8",
"cache-control": "no-store",
},
});
}
/*
* Advisory only. The real controls: `X-Robots-Tag` and `no-store` on /preview, and POST-only on
* /search/ask, which is disallowed because every answer is billed.
*/
const block = (agent: string) =>
`User-agent: ${agent}\nAllow: /\nDisallow: /admin\nDisallow: /lab\nDisallow: /preview\nDisallow: /search/ask\n`;
const body = [
...AI_AGENTS.map(block),
block("*"),
`Sitemap: ${origin}/sitemap.xml`,
`# LLM guide: ${origin}/llms.txt`,
"",
].join("\n");
return new Response(body, {
headers: {
"content-type": "text/plain; charset=utf-8",
"cache-control": HOURLY_CACHE_CONTROL,
},
});
}