Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Whatnot podcast).
## Commands

- **Dev server:** `pnpm dev` (runs on localhost:4321)
- **Build:** `pnpm build` (runs `astro check` then `astro build`)
- **Build:** `pnpm build` (runs `astro check`, `astro build`, then
`scripts/vercel-md-negotiation.mjs`, which injects `Accept: text/markdown`
content-negotiation routes into the Vercel build output)
- **Lint:** `pnpm lint` (ESLint with caching)
- **Lint fix:** `pnpm lint:fix`
- **All tests:** `pnpm test` (runs unit + e2e concurrently)
Expand Down Expand Up @@ -56,7 +58,11 @@ connection is configured in `db/index.ts`.

- `src/pages/` — Astro pages and API routes. Dynamic episode pages use
`[episode].astro`. LLM-friendly `.html.md.ts` endpoints generate markdown
versions.
versions. `openapi.json.ts` publishes an OpenAPI spec for the JSON API.
`[...notFound].astro` is an on-demand (prerender=false) catch-all that
returns agent-friendly 404s: JSON errors for `/api/*`, a markdown body for
`Accept: text/markdown` clients, and the styled 404 page otherwise. API
routes return structured JSON errors via `src/lib/api-errors.ts`.
- `src/components/` — Mix of `.astro` (static) and `.tsx` (Preact interactive)
components. The audio player (`src/components/player/`) and search dialog are
Preact.
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,40 @@ fine without them, using episode descriptions and metadata from your RSS feed.
All of the following endpoints are automatically generated at build time from
your `starpod.config.ts` and RSS feed:

- `/llms.txt` - Main discovery file
- `/llms.txt` - Main discovery file, including "when to use this site" guidance
for agents and a developer resources section
- `/for-llms` - Human-readable guide page
- `/for-llms.html.md` - Markdown version of guide
- `/index.html.md` - Markdown version of the homepage
- `/about.html.md` - Markdown version of about page
- `/contact.html.md` - Markdown version of the contact page
- `/episodes-index.html.md` - Complete episode listing
- `/{episode-slug}.html.md` - Individual episode with transcript
- `/{episode-number}.html.md` - Alternative episode URL
- `/openapi.json` - OpenAPI 3.1 spec describing the JSON API endpoints
(episode search, episode pagination, contact form)

No configuration needed - it just works!

#### Markdown Content Negotiation

Agents can also request any page that has a markdown twin with an
`Accept: text/markdown` header and get the markdown version back from the same
URL, per [acceptmarkdown.com](https://acceptmarkdown.com). Both variants are
served with `Vary: Accept` so CDNs cache them separately.

This is implemented by `scripts/vercel-md-negotiation.mjs`, which runs as part
of `pnpm build` and injects Accept-based rewrite routes into the Vercel build
output. If you customize the `build` script in `package.json`, keep the
`node scripts/vercel-md-negotiation.mjs` step after `astro build`. (Deploying
somewhere other than Vercel? The `.html.md` URLs still work everywhere; only
the Accept-header negotiation is Vercel-specific.)

#### Agent-Friendly Errors

- Nonexistent paths return a real HTTP 404: browsers get the styled 404 page,
`Accept: text/markdown` clients get a short markdown body pointing at the
sitemap, `llms.txt`, and the episodes index, and `/api/*` paths get a
structured JSON error
- API errors are structured JSON with a stable `error.code`, a message, and a
resolution `hint` - never an HTML error page
Loading