😱
Just a heads up, this is going to be a bit more of a technical post.

After years of working on web apps with React and design systems with Web Components, it's something of a homecoming to finally build a website again. I haven't had a website for myself since the mid-2010's; by that time, most of the work I picked up came through recruiters on LinkedIn, and I'd transitioned over to web application development (first with the now-bought-out iTimeKeep, built with Knockout at the time). To be honest, I missed working on websites.

The web has changed since then. Browsers weren't quite so consolidated (everything is basically Chrome now), and neither were websites. We live in a post-fight-for-web-standards world (I say this as someone who spent months convincing React developers to consider Web Components, my favorite new-to-me bit of web tech in the last five years), where we got most of what we wanted back in the late 2000's, with new layers of Stuff caked on top of our basic building blocks of HTML, CSS, and JavaScript. Some of it is cool (big fan of the lighter, low-config build tooling we have access to these days), some of it is a pain for questionable benefit (your tiny app with no room for growth doesn't need TypeScript).

I say all of the above to explain where I'm coming from in my decision-making process for how I put this site together.

The Stack

The Server

Starting from the lowest level, this site is hosted on a DigitalOcean droplet, running Ubuntu 23.10. DigitalOcean is inexpensive and stable (I can recall a single outage in my time using their services). I've been using it since early in the pandemic for hosting my FoundryVTT games.

I'm using nginx (as I have for the other projects on this droplet) for my server. While this is a requirement for my content management system (more on that in a sec), I'm also using it to route app servers to subdomains elsewhere in my setup (doorknocker uses separate subdomains for UI and API servers, for example).

Content Management

I chose Ghost, an open source Node-powered content management system, as my CMS because I've been curious about it since its early days. Compared to WordPress, it still has limitations (limited plugin integration, hence the Contact and Project Intake forms in the footer being built with Tally, for example), but it does what I need it to do, and it's quick enough for my purposes. I'm also much more familiar with JavaScript than I am with PHP these days. Lastly, the process for writing a theme is pretty similar to what I'm used to these days with building modules for Foundry, using Handlebars with vanilla JavaScript and CSS. My only gripe about Ghost is that I found its API documentation lacking; I had difficulty finding the shape of a post, for example.

Analytics

I wanted to avoid tracking users on this site, and as such, I collect no analytics. Ko-fi (which I use for the tip jar in the footer) and Tally may do so, but I felt that that was a necessary concession for getting solutions to the specific problems they solve, and they only execute code if you happen to open dialogs that contain their code. I considered using Umami to collect analytics, as privacy is one of their stated goals, and would consider using them in the future if I ever saw a reason to do so.

The Code

This site (or more specifically, the Ghost theme) uses Handlebars for templates, PostCSS for its styling, and vanilla JS bundled with Rollup for its behavior. I used Gulp to build my assets and manage live-reloading.

Handlebars

There isn't much to say about Handlebars, or Ghost's implementation of it. It's a solid template library, limited only by its commitment to keeping logic more complex than boolean comparison out of templates.

CSS

I'm not going to dunk on SCSS or LESS; they're useful tools, and I sorely missed SCSS's color functions when writing hover styles for buttons. These days, CSS can do most of what preprocessors used to do for us, with broader adoption of functions and variables in CSS.

I wrote my CSS by hand, using PostCSS to handle CSS nesting, auto-prefixing, and minification. I chose to write it by hand without the use of UI frameworks like Material UI, Tailwind, or Bootstrap mainly just to get my "reps" in, so to speak — I wanted to build my UI without additional tools to ensure that I still have my basics down. I also hoped to serve as little CSS as possible.

There are things in my styles that I'm unhappy with, of course. This site will probably always be under construction, and I'm at peace with that.

JavaScript

There isn't much to mention here, much like the Handlebars section above. I used vanilla JS, bundled up with Rollup, to write code for two different uses: the stars on the home page, and the dialogs in the footer.

Build Tooling

Webpack certainly, uh, exists, and I've really come to like using Vite. However, I thought that both tools were a little too weighty for the simple task of bundling assets for a theme on a website. I don't need a development server; the CMS already has a server. Instead, I opted for one of the older tools out there for this kind of work. Who out there remembers task runners?

So, my build tooling uses Gulp to run my CSS through PostCSS, run my JS through Rollup, and use LiveReload to refresh the page when I change a JS, CSS, or Handlebars file. It's not much, but it doesn't need to be much.

Conclusion

Hopefully this kind of peek into my decision-making process was helpful! I'll hopefully be able to provide as much or more insight into things I post over on the Projects page, too.

I'll try to keep this post updated with any changes I make to the site, as well as explain why I make them.