← Changelog

Content & Discovery Layer — RSS, Search, Blogroll

Content 2026-07-07

Built the site's content discovery infrastructure: dual RSS feeds (blog + notes), Pagefind client-side search with post-build indexing, and a static blogroll with live descriptions fetched at build time.

RSS feeds

Two feeds, intentionally separate:

/rss.xml — blog posts only. This is the primary feed — durable content, longer-form writing, the kind of thing feed readers want. Listed in RSS autodiscovery <link> in the page <head> so any RSS reader can find it automatically.

/notes-rss.xml — notes only. Notes are shorter observations, links, quick thoughts. Separate feed lets people subscribe to just that signal if they want. Many don’t.

The reasoning for the split: blog posts and notes have different publishing frequencies and different expectations from subscribers. Mixing them into one feed means blog readers get spammed with quick observations and note-subscribers miss the signal in longer posts.

RSS autodiscovery is added to Layout.astro so every page on the site points readers (and feed readers) to both feeds.

Pagefind — client-side search without the weight

Pagefind generates a search index at build time as a CLI step after astro build. The index is sharded into small binary files — only the shards relevant to a query are loaded, not the full index on page load. On a site this size, that’s typically a 20–40KB transfer per search, total, versus Fuse.js which loads a full JSON dump of every page’s content.

The tradeoff comparison:

PagefindFuse.js
Index size on loadSharded, load on queryFull JSON on page load
Build step requiredYes (CLI after build)No
AccuracyGood, weightedGood, fuzzy
CDN dependencyNoneNone if self-hosted
Offline supportYesYes

Setup: data-pagefind-body on <main> scopes the index to page content, excluding nav, footer, and the CrawlWidget. Individual pages can opt out entirely with a noindex Layout prop (crawl logs, 404, privacy).

Blogroll with live descriptions

The blogroll at /blogroll/ lists sites I read regularly. Each entry shows the site’s meta description, fetched from its homepage at build time using fetch() in Astro’s component script. The fetch happens once per build, the result is baked into the HTML — no runtime requests, no latency on page load.

The list is managed in Keystatic as a singleton with URL and optional fallback description fields. When a site doesn’t expose a usable meta description, the fallback is used instead.

Why static: Fetching descriptions at runtime would add external HTTP requests to every page load, with unpredictable latency and potential failures. Fetching at build time means the page always has a description (even if a site is temporarily down) and there’s zero runtime cost.

The RSS/feed icon appears in the nav alongside search, and in the footer social cluster alongside LinkedIn, GitHub, and X. On the homepage it’s also in the social strip. The icon is an inline SVG — the standard RSS broadcast symbol — no external image request.

← All entries