---
title: "How this site is built"
description: "What runs michael.zazon.us: Astro on Cloudflare Pages and posts I publish from Obsidian."
url: "https://michael.zazon.us/notes/how-this-site-is-built"
published: "2025-10-31T12:00:00-04:00"
kind: "build-log"
subject: "tools"
tags: ["obsidian","this-site"]
---
Short version: it's a static site on Cloudflare Pages, hosting costs nothing, and I publish posts from Obsidian without opening a terminal.

For years my "website" was a LinkedIn profile and a résumé on VisualCV. Recently I replaced both with this site. (Why I bothered is its own post: [Why I built this site](https://michael.zazon.us/notes/why-i-built-this-site).)

It's built with [Astro](https://astro.build). There's no server and no database, just HTML files that [Cloudflare Pages](https://pages.cloudflare.com) serves from its edge. The source lives in a private GitHub repo with a mirror on my home server. Every pull request gets its own preview URL and runs the checks: linting, type checks, tests against the built pages, an HTML validator, a link checker, and Lighthouse, which has to score at least 90 in every category.

I looked at sixteen design directions before picking one, and the first version leaned on an album liner notes idea, with numbered tracks and a small catalog mark. It looked clever in a mockup. On the live page it was noise, so I took it out. What's left is two typefaces and one column. Most people who land here want my résumé or a way to reach me, and I'd rather not make them hunt for either.

The fonts are Newsreader, Barlow and DM Mono, all served from this site instead of Google Fonts. I started with the variable version of Newsreader, which weighed 280 KB and pushed the largest paint on the page to almost three seconds. Static cuts fixed that. The one thing I missed was the heavier headline, so the h1 now has its own 21 KB file, cut from the variable font at the 72-point optical size.

Posts start as notes in [Obsidian](https://obsidian.md), where I already write everything else. A post is a note with a title, a one-line description and a date. When it's ready I flip one property, `share: true`, from my laptop or my phone, and that's the last thing I touch.

Obsidian Sync carries the note to my home server, which runs Obsidian in a container. Once an hour a small script looks for posts that changed, and when it finds one it tells [Enveloppe](https://github.com/Enveloppe/obsidian-enveloppe), an Obsidian plugin, to publish it. Enveloppe opens a pull request with the Markdown, the pull request merges itself, and Cloudflare builds the site.

I'm particularly excited about edits.. if I want to add something to a post, clarify or correct something, I simply make the change with Obsidian or any text editor, save it, and it goes out with the next hourly check. Or right away if I tell Enveloppe to push and merge.

[Diagram: How a post gets from Obsidian to the live site](https://michael.zazon.us/notes/how-this-site-is-built)

The date is how scheduling works. The build leaves out any post dated in the future, so it isn't in the index, the RSS feed or anywhere else until its day. A GitHub Action starts a fresh build every morning, and whatever is dated that day shows up. Days are New York days, so a post dated Tuesday goes live Tuesday morning here, not at midnight UTC.

Each post also gets its own preview card for LinkedIn and anywhere else that shows one. The build draws it as a PNG from the post title, in the same fonts as the site.

Is it a lot of machinery for a personal site? Probably a little. But it runs itself, it costs nothing to host, and I can publish from my phone, which is all I really wanted.