Note

Building this website was worth it

Building this website has taken a long time, and that is okay. The process has been more than worth it.

Why the process mattered

Through the refactors, I have been able to work towards cleaner boundaries, cleaner code, thorough testing, and a working CLI publishing pipeline.

Boundaries are not for fun

Boundaries are not just an architectural preference. They allowed me to visualise the content model more clearly and support the evolution of the website without turning the application into a tangled mess.

Throughout the application, the authored shape stays as flexible and simple as possible. That matters because it keeps writing content manageable and comfortable.

AppState provides the right content to the XML sitemap, internal linking, breadcrumbs, and shared runtime structures.

AppContext then constructs and resolves the page, ensuring that inline content and content blocks have all the information they need before rendering begins.

AppRenderContext, or ARC, simplifies the resolved page into a deterministic render-ready object for the renderer to consume.

This methodology allows the content to remain flexible while making the application deterministic at the first sensible opportunity. The authoring layer stays comfortable, while the application does the heavy lifting.

The painful CLI

The CLI is complex because it has to support multiple publishing and authoring flows while still making content creation manageable for me.

It is also completely standalone Node code outside the normal application runtime, meaning it has its own configuration, quirks, and edge cases.

Because it sits outside wrangler, additional complications appear when dealing with Cloudflare services such as KV and Images.

Painful at times, yes — but also necessary. The CLI turns the website from something deployable into something publishable.

Testing

I used ChatGPT to help generate a large amount of the test scaffolding because there are simply a lot of tests throughout the project.

I specifically wanted sibling tests so that test files stay physically close to the implementation they protect. That keeps maintenance clearer and avoids losing visibility over which tests belong to which functions and branches.

The target is 100% coverage across statements, branches, functions, and lines. While that can sound like vanity, in practice it forces difficult parts of the codebase into the spotlight.

Coverage pressure often revealed awkward branching, unnecessary complexity, or unclear boundaries. More often than not, the result was cleaner and more maintainable code.

Summary

In the end, the work paid off. I learned a huge amount throughout the process, and I now finally have a website that genuinely works for me instead of against me.

Just as importantly, I can carry many of these lessons into my professional work as well.