Blog / Content
Newsletter archive list
Numbered issues with subjects and open rates
Numbered issues with subjects and open rates
Build a newsletter archive page with Tailwind CSS. The header block has a heading, a paragraph about what the letter covers and how often it lands, and an inline subscribe row of an email input and a dark button with a muted line under it giving the subscriber count. Below, a list of eight issues rendered as rows separated by hairlines rather than cards: each row has a monospaced issue number on the left in a fixed-width column, then the subject line in medium weight with a muted one-line summary underneath, and on the right the send date in muted small text with a tiny "Read" link that appears on hover. Give the most recent issue a small green "Latest" pill beside its subject. Under the list, a centred bordered "Load older issues" button and a muted line noting the archive goes back to 2023. <section class="mx-auto max-w-3xl px-6 py-16">
<h1 class="text-4xl font-semibold tracking-tight text-neutral-900">The Thursday Letter</h1>
<p class="mt-4 max-w-xl leading-relaxed text-neutral-500">
One email a week about building and running data infrastructure — what broke, what we changed, and the occasional strong opinion about column stores.
</p>
<form class="mt-7 flex max-w-md gap-2">
<input type="email" placeholder="[email protected]"
class="min-w-0 flex-1 rounded-xl border border-neutral-200 px-4 py-2.5 text-sm outline-none transition focus:border-neutral-900 focus:ring-4 focus:ring-neutral-900/10" />
<button class="shrink-0 rounded-xl bg-neutral-900 px-5 py-2.5 text-sm font-medium text-white transition hover:bg-neutral-800">Subscribe</button>
</form>
<p class="mt-2 text-xs text-neutral-400">14,200 readers · one click to leave, no hard feelings.</p>
<div class="mt-12 divide-y divide-neutral-200 border-y border-neutral-200">
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#48</span>
<span class="min-w-0 flex-1">
<span class="flex flex-wrap items-center gap-2">
<span class="text-sm font-medium text-neutral-900">The query planner is not your enemy</span>
<span class="rounded-full bg-green-100 px-2 py-0.5 text-[10px] font-medium text-green-700">Latest</span>
</span>
<span class="mt-1 block text-sm text-neutral-500">Reading an EXPLAIN output without pretending you understood it the first time.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">14 Aug</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#47</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">We deleted our staging environment</span>
<span class="mt-1 block text-sm text-neutral-500">Six weeks of ephemeral environments later, nobody has asked for it back.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">07 Aug</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#46</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">Backfills, and the art of not melting production</span>
<span class="mt-1 block text-sm text-neutral-500">Rate limits, checkpoints and knowing when to just let it take a week.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">31 Jul</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#45</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">Nobody reads your dashboard</span>
<span class="mt-1 block text-sm text-neutral-500">What happened when we instrumented the analytics tool with itself.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">24 Jul</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#44</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">A schema migration in four acts</span>
<span class="mt-1 block text-sm text-neutral-500">Expand, backfill, contract, and the long wait in between.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">17 Jul</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#43</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">On-call is a product decision</span>
<span class="mt-1 block text-sm text-neutral-500">Every unpaged incident is a feature someone else has to build twice.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">10 Jul</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#42</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">Cheap tricks for faster dashboards</span>
<span class="mt-1 block text-sm text-neutral-500">Six changes that cost nothing and one that cost a fortnight.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">03 Jul</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
<a href="#" class="group flex items-start gap-5 py-5 transition hover:bg-neutral-50">
<span class="w-10 shrink-0 font-mono text-sm text-neutral-300">#41</span>
<span class="min-w-0 flex-1">
<span class="text-sm font-medium text-neutral-900">The cost of a column</span>
<span class="mt-1 block text-sm text-neutral-500">Adding one field to a hot table, priced out end to end.</span>
</span>
<span class="shrink-0 text-right">
<span class="block font-mono text-xs text-neutral-400">26 Jun</span>
<span class="mt-1 block text-xs font-medium text-neutral-900 opacity-0 transition group-hover:opacity-100">Read <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></span>
</span>
</a>
</div>
<div class="mt-10 text-center">
<button class="rounded-xl border border-neutral-200 px-5 py-2.5 text-sm font-medium text-neutral-700 transition hover:bg-neutral-50">Load older issues</button>
<p class="mt-3 text-xs text-neutral-400">The archive goes back to issue #1, November 2023.</p>
</div>
</section>