feat(seo): site config, sitemap, robots.txt, llms.txt and a real 404 page

- astro.config: site, trailingSlash "never", build.format "file".
- /sitemap-index.xml + /sitemap-0.xml as prerendered endpoints (no new
  dependency); pages are derived from src/pages/*.astro, 404 excluded.
- robots.txt: all bots allowed, AI crawlers/training bots explicitly
  allowed (Linus's decision), /download/ disallowed, sitemap line.
- /llms.txt generated from business.ts, incl. usage-with-attribution note.
- 404.astro in Swedish with links back, noindex.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WvE3C43Uwtv2vtnoFBLDw7
This commit is contained in:
Linus Olofsson
2026-10-27 19:13:07 +01:00
co-authored by Claude Opus 5.5
parent 30e385ec7f
commit f452d6d237
7 changed files with 198 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
// src/pages/sitemap-0.xml.ts -> /sitemap-0.xml
// Listar sajtens riktiga sidor (inte 404). Ingen <lastmod>: vi har inget
// pålitligt ändringsdatum per sida, och ett påhittat datum gör mer skada än nytta.
import type { APIRoute } from 'astro';
import { sitePaths } from '../lib/pages';
export const prerender = true;
const escapeXml = (s: string) =>
s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
export const GET: APIRoute = ({ site }) => {
const base = site ?? new URL('https://imagesbyolofsson.se');
const urls = sitePaths()
.map((p) => ` <url><loc>${escapeXml(new URL(p, base).toString())}</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' } });
};