techy schmechy

Rescuing a Frozen Frontity Portfolio by Rebuilding It in Astro

In April 2023 I pushed a one-line change to this site’s menu. It reached GitHub. It never reached production. I did not notice for three years.

The site kept serving — a build from June 2022, frozen, looking fine. That is the part worth sitting with: a deploy pipeline that fails silently is indistinguishable from one that works, right up until you try to change something.

Three failures, not one

The stack was Frontity — React, Chakra, Emotion, framer-motion, Overmind — which Automattic archived in 2022. Building locally failed on modern Node, because webpack 4 hits the OpenSSL changes that broke a generation of JavaScript tooling. And Vercel still held dashboard settings from the original project, including a build command of frontity build that survived every attempt to change the framework.

Any one of those alone is a bad afternoon. Together they meant the repository could not tell you why the site was stuck, because a third of the problem lived outside the repository.

Rebuilding it

The site is a portfolio backed by WordPress. Almost every page is text and images. It was shipping a full client-side React runtime to render them.

It runs on Astro now, statically built. WordPress is still the CMS — the content workflow was never the problem. There is a real constraint there: the free WordPress.com plan does not expose /wp-json/wp/v2 on the site’s own domain and cannot install plugins, so WPGraphQL and every tutorial that assumes it are unavailable. Content comes through the public REST proxy instead.

Every old URL still resolves. Post paths are read from the permalink WordPress reports rather than reconstructed from dates, so a permalink change in WordPress cannot silently orphan a page.

Making the failure impossible to repeat

The deployment settings that broke it now live in the repo instead of a dashboard, where a diff can show them.

Content freshness needed a different answer. WordPress.com cannot install a webhook plugin, so nothing can notify the site when a post changes. The build publishes a fingerprint — a hash of every published post’s ID and modified date — and a scheduled job compares that to what WordPress reports right now, rebuilding only when they differ. Comparing against the deployed artifact means there is no stored state to go stale, and a manual redeploy fixes the comparison automatically.

The site ships static HTML and CSS with a couple of kilobytes of inline JavaScript for search and the mobile menu. The old build sent around 830KB of framework to do the same job.

The interesting part was never picking Astro. It was that the thing which broke this site was not in the code, and no amount of reading the repository would have found it.