Sitemap, robots.txt & llms.txt — Static vs. Dynamic

All six now have robots.txt and sitemap.xml — that part costs nothing on any of them. llms.txt (the llmstxt.org convention — a plain-markdown sitemap equivalent aimed at LLM crawlers/retrievers) is where it splits.

Stackrobots.txtsitemap.xmlllms.txtHow it's produced
vanilla-statichand-authored, static
vanilla-spahand-authored, static
site-servergenerated at startup from real pages + trails.json
reacthand-authored, static
vuehand-authored, static
angularhand-authored, static
The difference that matters isn't the checkmark, it's what happens when content changes. The five static robots.txt/sitemap.xml files were hand-typed once for this 3-page demo and will silently go stale the moment a page is added, renamed, or removed. site-server's three files are regenerated from the real wwwroot/pages/ directory and the real trails.json every time the process starts — they cannot drift from what's actually there. That's the genuine advantage: not "has a file," but "the file can't lie."
A methodology trap we caught while measuring this: requesting a nonexistent /llms.txt against vanilla-spa (serve -s) and react/vue (vite preview) returned HTTP 200 with the index.html shell's content — their SPA-fallback rewrite serves the shell for any unmatched path, not a real 404. A real production deploy configured the same way would do the same thing to a crawler checking for the file, which is arguably worse than a clean 404: it looks like content exists when it doesn't. angular's static server (no fallback flag) correctly returned a real 404 instead.