Every issue we've published, plus the metadata that describes it. This repo is
the source of truth — meridianalgo.org/newsletters
reads manifest.json from here at page load, so publishing an issue means
pushing to this repo. No website deploy needed.
manifest.json index of every issue + series metadata
issues/ the PDFs
thumbnails/ one cover image per series
validate.mjs checks the manifest against what's on disk
Top level:
| Field | Meaning |
|---|---|
version |
Manifest schema version. Bump only on a breaking change. |
updated |
YYYY-MM-DD of the last edit. |
readBase |
jsDelivr base URL. Serves application/pdf, so PDFs render inline in the browser. |
downloadBase |
raw.githubusercontent base URL. Forces a file download. |
series |
One entry per publication (id, name, description, thumbnail). |
newsletters |
The issues, newest first. |
Each issue:
{
"id": "smart-cents-weekly-week-19",
"title": "Smart Cents Weekly — Week 19",
"description": "One sentence on what this issue covers.",
"series": "smart-cents-weekly",
"seriesName": "Smart Cents Weekly",
"week": 19,
"category": "Budgeting",
"publishedDate": "2024-03-27",
"file": "issues/smart-cents-weekly-week-19.pdf",
"thumbnail": "thumbnails/smart-cents-weekly.png"
}id must be unique and file must exist — validate.mjs enforces both.
category is free text; the site turns the distinct values into filter chips.
Two optional fields:
| Field | Meaning |
|---|---|
topics |
Short tags for what the issue covered. Keeps later issues from going over the same ground. |
headline |
The issue's own headline, as distinct from title (which is always <Series> — Week N). |
The manifest is public and CORS-enabled — anything can read it:
const res = await fetch('https://raw.githubusercontent.com/MeridianAlgo/newsletters/main/manifest.json');
const { readBase, newsletters } = await res.json();
const latest = newsletters[0];
console.log(latest.title, readBase + latest.file);Newsletter content © MeridianAlgo. Free to read and share with attribution.