← All projects

Lifetechfacts

A tech blog I wrote for, and built the reading experience for.

Lifetechfacts screenshot
2022–2023
Ran
1s
ISR revalidate
0
Tests
01

The problem

I was writing the posts as well as building the site, which made the trade-off concrete: WordPress is the best writing and editing experience available, and one of the worst reading experiences you can serve. I wanted the editor without the front end.

02

What I built

A Next.js reading front end over headless WordPress. Posts, categories, tags and search come from the WordPress REST API and render as static pages that revalidate in the background, so publishing an edit updates the site without a rebuild and a reader never waits on the CMS.

On top of that: syntax highlighting for code posts, an installable offline-capable build, share cards, dark mode, and a table of contents lifted out of the post body.

03

Decisions I'd defend

Incremental static regeneration was the whole point. A blog is read far more than it is written, the content is public, and the CMS is the slow part; serving static HTML that refreshes itself gets the editing experience and the reading experience at once.

The table of contents is extracted from the rendered WordPress HTML and its anchors rewritten. It is string surgery on someone else’s markup and I would not call it clean, but the alternative was asking a writer to maintain a second structure by hand, and writers do not do that.

04

What I would do differently

Two features looked finished and were not. Comments render but cannot be posted: the submit call is written and never wired to the button. The "write for us" page is a complete form with no submit handler at all. Both shipped looking live, which is worse than not shipping them, and both are the kind of thing one integration test would have caught.

The companion API was thinner than it appeared, and one part of it was wrong in a way worth naming: enrolment confirmation was sent on the basis of a payment flag supplied in the request body. A client can say anything. Payment state has to come from the payment provider, verified server-side, and that is the lesson I carried into every checkout I have built since.

05

Where it is now

Shut down, and the domain has lapsed. The audience moved to the community I still run.