status: active
timestamp: 2026-06-20
tags: [linkroll, raindrop, blog, build-time, deploy]
Linkroll — Raindrop.io is source of truth, blog.oriz.in/links built at deploy time
Family linkroll lives in public Raindrop.io collection blog.oriz.in/links is built at deploy time from the Raindrop REST API. Cached via the Cloudflare edge with a 1-hour TTL on the build artifact; nightly cron re-deploys to surface new links.
Linkroll — Raindrop.io is source of truth, blog.oriz.in/links built at deploy time
Decision
The family’s “things I’ve been reading” linkroll lives at
blog.oriz.in/links. Its source of truth is a public collection on
Raindrop.io.
The page is statically built at deploy time from a
fetch() against the Raindrop REST API. No Worker call per
pageview; no client-side hydration. The build artifact is served by
Cloudflare Pages, with
the page cached at the edge per the family _headers preset (1-hour
s-maxage on /links HTML so the next-deploy bump propagates fast).
A nightly GitHub Actions schedule
trigger re-deploys oriz-blog-site so additions made in Raindrop
during the day surface without a manual push.
For each linkroll item, the build also mints (or reuses) an
s.oriz.in/<slug> short URL via the
Cloudflare Worker shortener —
that’s the URL oriz-omnipost cross-posts when sharing links to
aggregator platforms.
Why
- Build-time fetch costs zero per pageview. Pageviews hit the CF edge cache, never the Raindrop API. Quota anxiety on the Raindrop side is bounded by the cron cadence (=24 builds/day worst case).
- Static
/linksis the shape we already use. Same Astro build produces it as the rest of the blog. No new runtime, no new Worker, no new infra surface. - Raindrop is the family’s existing bookmark capture flow. Browser extensions work, mobile apps work, the user’s day-to-day bookmarking already lands there. Building the linkroll on top of that flow rather than introducing a parallel system means there’s one place to add a link.
- Free, no card. Per
services/business/social/raindrop-io.md.
Implications
oriz-blog-sitereadsRAINDROP_TOKENfrom Doppler. The token authorises a single read-only collection scope.- Build step calls
GET https://api.raindrop.io/rest/v1/raindrops/<collection-id>?perpage=200and persists the result as JSON for the page render step. - A nightly GH Actions cron in
oriz-blog-sitetriggers a Cloudflare Pages deploy (gh workflow runon the existing CI workflow with aforce-rebuildinput) so additions made during the day land without a manual push. - For each item, the build looks up an existing
s.oriz.in/<slug>mapping or creates one if absent (idempotent on the Raindrop item ID). This is the URLoriz-omnipostcross-posts. - A daily JSON export of the collection lands in
oriz-me-data/exports/raindrop-<date>.jsonas a backup — Raindrop is canonical operationally but the family keeps a rebuilt-from-git snapshot in case of vendor disappearance.
What we don’t do
- No client-side fetch. Hides the API surface from public scraping and avoids token-handling on the browser side.
- No per-pageview Worker proxy. Would burn CF Workers quota for zero readability benefit; the cron-on-build cadence is enough.
- No vendor lock-in. Cleartext JSON export to
oriz-me-datameans the linkroll survives Raindrop disappearing on a week’s notice.
Cross-refs
- Raindrop.io service entry
- s.oriz.in shortener
- URL-shortener quota mitigation decision
- Cloudflare Pages
- GitHub Actions schedule
- Cross-post engine — consumer of the s.oriz.in mints
- No card-on-file rule