<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://anthonyboffman.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://anthonyboffman.com/" rel="alternate" type="text/html" /><updated>2026-07-12T06:04:33-07:00</updated><id>https://anthonyboffman.com/feed.xml</id><title type="html">Anthony Boffman</title><subtitle>Senior Fullstack Engineer — enterprise systems, shipped with AI leverage.</subtitle><entry><title type="html">Static site, real CMS, zero servers</title><link href="https://anthonyboffman.com/blog/static-site-real-cms-zero-servers/" rel="alternate" type="text/html" title="Static site, real CMS, zero servers" /><published>2026-07-11T00:00:00-07:00</published><updated>2026-07-11T00:00:00-07:00</updated><id>https://anthonyboffman.com/blog/static-site-real-cms-zero-servers</id><content type="html" xml:base="https://anthonyboffman.com/blog/static-site-real-cms-zero-servers/"><![CDATA[<p>This site is deliberately boring infrastructure: hand-written HTML and CSS on GitHub Pages, no frameworks, no build step. Adding a blog usually breaks that — a “dashboard with a login” sounds like a server, a database, and a monthly bill.</p>

<p>It doesn’t have to be. Here’s the whole stack behind the post you’re reading:</p>

<h2 id="the-publishing-path">The publishing path</h2>

<ol>
  <li>I write in <a href="https://pagescms.org">Pages CMS</a> — a hosted dashboard with a rich text editor and image uploads. Login is just my GitHub account.</li>
  <li>Hitting publish commits a markdown file to this repo, images included.</li>
  <li>GitHub Pages notices the push and runs Jekyll — the static site generator it has had built in since forever — which turns the markdown into a real HTML page.</li>
</ol>

<p>No servers of mine anywhere in that path. The “database” is a git history, which means every post is version-controlled, diffable, and portable by default.</p>

<h2 id="why-not-client-side-rendering">Why not client-side rendering?</h2>

<p>The tempting shortcut is to fetch markdown with JavaScript and render it in the browser — zero build, fully static. The problem is sharing: LinkedIn’s link crawler doesn’t execute JavaScript, so every shared post would show the same generic preview card.</p>

<p>Jekyll renders each post to its own URL with its own Open Graph tags at deploy time:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:title"</span> <span class="na">content=</span><span class="s">"Static site, real CMS, zero servers"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:type"</span> <span class="na">content=</span><span class="s">"article"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:image"</span> <span class="na">content=</span><span class="s">"https://anthonyboffman.com/assets/og-image.png"</span><span class="nt">&gt;</span>
</code></pre></div></div>

<p>That’s the difference between a link and a card.</p>

<blockquote>
  <p>The best infrastructure is the kind you can explain in three bullet points and forget about for a year.</p>
</blockquote>

<h2 id="what-it-costs">What it costs</h2>

<p>Nothing. GitHub Pages hosting is free, Jekyll runs inside it, and Pages CMS is free for this use case. The only maintenance surface is a single YAML config file in the repo.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[How this blog works: markdown in a GitHub repo, rendered by Jekyll on GitHub Pages, written from a hosted rich-text dashboard — no servers, no database, no build pipeline to babysit.]]></summary></entry></feed>