Add dynamic sitemap.xml and Atom feed

Add dynamic sitemap.xml and Atom feed

#4 in tonybierman/dx-blog — merged 2026-05-29

What

Two public XML endpoints for SEO and feed readers:

  • GET /sitemap.xml — home + archive landing pages, every published post (with <lastmod>), and each category / tag / author index that has published content.
  • GET /feed.xml — Atom 1.0 feed of the 20 most recent published posts, with the full rendered HTML in each entry's <content type="html">.

Plus an Atom autodiscovery <link> in the document head so readers/browsers find /feed.xml automatically.

How

  • New src/server/feeds.rs — plain axum GET handlers (server-only). Raw XML with custom content-types can't go through the Dioxus server-fn wire format, so these aren't server functions. Registered on the router in main.rs; they reach the shared pool via the Extension<Pool> that arium's install() layers over the whole router.
  • XML is hand-built with a small escape helper — no new crates.

Why Atom over RSS

Atom's timestamps are RFC 3339, a trivial reshaping of SQLite's datetime('now') output (space → T, append Z). RSS's RFC 822 dates would need weekday/month-name computation — i.e. a date dependency. Atom is universally supported by feed readers, so nothing is lost.

Config

  • SITE_URL — canonical origin for absolute URLs (trailing slash trimmed; defaults to http://localhost:3000).
  • SITE_TITLE — feed <title> (defaults to dx-blog).

Both documented in .env.example.

Verification

  • Both targets type-check clean (server,sqlite and web wasm).
  • Ran a freshly-built server binary against the seeded DB and confirmed:
    • /sitemap.xmlapplication/xml, valid <urlset> with posts/categories/tags/authors and per-post <lastmod>.
    • /feed.xmlapplication/atom+xml, valid feed with RFC 3339 timestamps, authors, summaries, and XML-escaped HTML content.
    • SITE_URL trailing-slash trimming and SITE_TITLE escaping both work.

🤖 Generated with Claude Code

Last updated 2026-05-30