Atom Feeds
Every table-backed template page exposes an Atom 1.0 collection feed at its static path prefix plus /feed.xml. The feed lists the newest 20 published rows as entries — publish a table-backed blog and readers subscribe at /posts/feed.xml.
/posts/:slug→/posts/feed.xml/:slug(root template) →/feed.xml
Discovery
The template page (and every row page rendered from it) includes an Atom autodiscovery <link rel="alternate" type="application/atom+xml"> tag pointing at the collection feed, so feed readers and agents can find the feed from any row page without knowing its URL.
Entry fields
Each entry maps row data to Atom by field-name convention:
| Element | Source |
|---|---|
id |
Stable tag URI derived from the canonical host (tag:example.com,2026:row/{id}) — the same row keeps one id across mirrors and deploys |
link |
Absolute permalink to the row's canonical URL |
title |
title or name field, falling back to the slug (or last placeholder) value |
content |
content or body field, served as escaped HTML |
summary |
summary, description, or excerpt field, escaped HTML |
published / updated |
Row publish / modification timestamps |
Only the entry title is required — content and summary are omitted when the row has no matching fields.
Rules
feed.xmlis reserved — rows can't use it as a placeholder value; validation rejects it. Page paths can't contain dots, so no other URL can collide with a feed.- Ambiguous prefixes 404 — if two template pages share the same static path prefix, the feed URL is ambiguous and returns 404; the autodiscovery link is omitted in that case too.
- Drafts are excluded — feeds list published rows only, sorted by
published_at, newest first. On dev environments drafts are included, mirroring preview behavior.
Caching
Feeds serve ETag and Last-Modified and answer conditional requests (If-None-Match, If-Modified-Since) with 304 Not Modified — cheap for frequent pollers.
When the table has 20 or fewer published rows, the feed is marked complete per RFC 5005 (<fh:complete/>) — readers can treat a disappearing entry as deleted rather than aged off the cap.