Mijn Eigen Nieuwsbrief Bouwen met Claude
Dag twee van de Hacker News verkeersspits. Veertigduizend bezoekers, geen manier om ze opnieuw te bereiken. Ik had een nieuwsbrief aanmelding nodig.
Ik keek naar Buttondown, Beehiiv, Substack, ConvertKit. Allemaal overdreven. Ik moest alleen e-mailadressen verzamelen. Ik had geen campagnes, analyses of abonneebeheer nodig. En ik wilde eigenaar zijn van mijn gegevens.
Dus vroeg ik Claude om het te bouwen.
flowchart LR
User([User]) --> Form[Newsletter Form]
Form -->|POST /api/subscribe| Worker[Cloudflare Worker]
Worker --> KV[(Cloudflare KV)]
KV -.->|Daily sync| GHA[GitHub Actions]
GHA -.-> Repo[(subscribers.jsonl)]
flowchart TB
User([User]) --> Form[Newsletter Form]
Form -->|POST /api/subscribe| Worker[Cloudflare Worker]
Worker --> KV[(Cloudflare KV)]
KV -.->|Daily sync| GHA[GitHub Actions]
GHA -.-> Repo[(subscribers.jsonl)]
De Opzet
Ik gaf Claude een Cloudflare API-token via een omgevingsvariabele en beschreef wat ik wilde: een formulier dat e-mailadressen verzamelt en opslaat op een plek die ik beheer.
Minder dan 30 minuten later had ik een werkende nieuwsbrief.
Wat Claude Bouwde
| Component | Technologie |
|---|---|
| Formulier | HTML + vanilla JS |
| Backend | Cloudflare Worker |
| Opslag | Cloudflare KV |
| Synchronisatie | GitHub Actions |
Het formulier is een Hugo partial die post naar /api/subscribe:
<form id="newsletter-form">
<input type="email" name="email" placeholder="[email protected]" required>
<button type="submit">Subscribe</button>
</form>
De backend is een 42-regels Cloudflare Worker die validatie, normalisatie, duplicaatdetectie en referer-sanitisatie afhandelt:
export async function onRequestPost(context) {
const { email } = await request.json();
// Validate, normalize, check for duplicates
const emailKey = email.trim().toLowerCase();
const existing = await env.SUBSCRIBERS.get(emailKey);
if (existing) {
return Response.json({ success: true, message: "Already subscribed" });
}
// Sanitize referer (strip query params for privacy)
const referer = request.headers.get("Referer");
const source = referer ? new URL(referer).origin + new URL(referer).pathname : "direct";
// Store in KV with metadata
await env.SUBSCRIBERS.put(emailKey, JSON.stringify({
subscribedAt: new Date().toISOString(),
source
}));
return Response.json({ success: true }, { status: 201 });
}
Snelheidsbeperking komt van Cloudflare’s ingebouwde bescherming—geen extra code nodig.
Een GitHub Actions workflow draait dagelijks om abonnees van Cloudflare KV te synchroniseren naar een JSONL-bestand in de repo. Mijn abonneelijst leeft in versiebeheer. Als Cloudflare morgen mijn account sluit, heb ik nog steeds mijn gegevens. En het is in een formaat waarmee LLM’s gemakkelijk kunnen werken.
De Workflow
Claude itereerde lokaal totdat alles werkte—formulierinzending, KV-opslag, foutafhandeling. Daarna naar een preview-app gepusht, de volledige flow getest en samengevoegd met main.
Het formulier ging live terwijl het verkeer nog stroomde.
Dit hele ding werd gebouwd in één sessie.
Waarom Geen SaaS?
Buttondown is geweldig als je het nodig hebt. Ik niet. Mijn vereisten:
- E-mailadressen verzamelen
- Ze opslaan op een plek die ik beheer
- Snel lanceren
Dat is het. Ik heb geen drip-campagnes of A/B-testen of mooie sjablonen nodig. Ik heb een lijst met e-mailadressen nodig die ik bezit.
42 regels code in plaats van nog een maandelijks abonnement. Soms is de eenvoudige oplossing de juiste.
De conclusie: onvolmaakt en live verslaat perfect en gepland. Ik had uren kunnen besteden aan het evalueren van nieuwsbriefservices, het vergelijken van functies, het lezen van reviews. In plaats daarvan lanceerde ik iets in 30 minuten en ging verder.