GrantTroveGrantTrove Docs
Using the product

The weekly digest

What the newsletter contains, what it will never contain, and the exact file an issue is.

A weekly summary of what entered the catalogue and what closes next. Every issue is also a page at /newsletter, permanently.

Subscribing

One address, no account, no card. Every message carries an unsubscribe link that works without signing in.

If what you want is narrower than everything — one applicant type, one state, one field — that is an alert rather than the digest, and it reports what changed rather than what exists.

What an issue may contain

Three rules, and they are enforced by the file format rather than by whoever writes the issue.

Every entry names a record. Each item carries the slug of a record in the catalogue and renders as a link to it. An issue cannot carry an opportunity you are unable to open, which is what keeps it a summary of the data rather than editorial copy about the sector.

Every figure carries the date it was taken. An issue is a photograph of a catalogue that moves. The counts in it describe the day they were counted, and the page says which day rather than recomputing them when you open it — a page that recomputed would silently rewrite an old issue every time someone read it.

Absence stays absence. A deadline or a ceiling the source did not publish renders as Not stated, not as a blank cell. A blank in an email is read as a zero exactly as a blank in a table is. See reading provenance.

Nothing in an issue is sponsored, paid for, or placed.

The file an issue is

An issue is one file in content/newsletter/, validated by the newsletter collection in source.config.ts. That schema is the contract between whatever generates a digest and the pages that render it; changing the shape means changing it there, where both halves can see it.

---
issue: 1                       # monotonic integer; the URL is the date, not this
date: "2026-09-12"             # the day the issue covers up to, and its slug
windowDays: 7                  # how far back the issue looks
dataAsOf: "2026-09-12"         # when the counts were taken
title: "Issue 001"
description: "One quotable sentence about this issue."
counts:
  newlyAdded: 0                # records linked inside the window
  closingSoon: 0               # records closing inside the window
  catalogueTotal: 0            # records in the catalogue on dataAsOf
sections:
  - heading: "Newly added"
    items:
      - slug: "2026-dairy-plus-program"   # must resolve to /grants/<slug>
        title: "2026 Dairy Plus Program"
        funder: "California Department of Food and Agriculture"
        deadline: "2026-11-01"            # ISO date, or null
        amountMax: 1250000                # whole dollars, or null
        note: "Ceiling qualified per unit"   # optional; the source's wording
---

deadline and amountMax are nullable rather than optional. Null means the source did not state it, and the page prints Not stated; a zero or an empty string would reproduce in an email the exact misreading the three absence states exist to prevent.

A file missing any required field fails the build and names itself.

Where issues come from

The generation step is a pipeline concern and lives outside these pages. What lives here is the contract above and the two routes that read it — /newsletter and /newsletter/<date> — so a generated issue is publishable the moment it is written, and an issue written by hand is subject to exactly the same rules.

Table of Contents