Building blocks and choices

Something that surprised me is the history of the personal webpage can be found mostly on Wikipedia here, I'll forgo my own narrative of it as I have really only been on the web the last 15 years

The personal webpage has evolved in the last 40 years.

Originally the web was only in document form. People would throw up HTML only pages to represent themselves or their hobbies. They would style them with tables. Then inline CSS. Then finally external style documents.

The web evolved semi-organically and as more and more features were introduced to browsers the opportunity for greater artistic and creative expression presented itself.

Often times though when I think of the personal webpage I think of what you would see on an academic website like this:

Static Site Generators

As the one page webpage began to spin out to multiple pages, individual programmers got tired of copying and pasting (to be honest it must be acknowledged that laziness has to take a role in this as well) stylesheets and markup from page to page.

The use of functions to generate HTML and CSS began to proliferate through the web development community.

Individuals began to realize that they could write frameworks that would spit out a pile of HTML, Javascript and CSS that could be uploaded to servers in a reproducible way.

(Believe it or not there is also a Wikipedia page on static site generators here, the list is woefully way to short, you can also check out a more comprehensive list here on Github or even more comprehensively here )

Once you realize that you only need a simple templating language or you can invent your own and start gluing other technologies together you are off. The difficulty of actually creating one of these things isn't out of an introduction to programming class or one shortly after it. In fact I would say building two or three on your own and messing up is a great way to generally learn what you do and do not want from a website. Which leads me to...

This website

A few years ago I got fed up with whatever static website generator I was using. I think it was likely Yeoman which was slowly being abandoned by it's original creators (who also spawned/abandoned great tools like Bower - which inspired and then was crushed by NPM - the early 2010s were weird, so many formative ideas which have bled into the state of the current web...everything Jeremy Ashkenas did was revolutionary and inspiring to me as a young web developer).

Having been burnt once or thrice by these static website generators and having written one that tried to overly leverage clever design principles, I decided to focus on creating a framework that spit out fairly decoupled HTML, Javascript and CSS. The stack would look like this:

  • PugJS - Should be named Jade. Was a fan of this style of templating that depended on indentation. I would use this to generate my HTML. The fact that it has filters meant that I could extend it in any direction I like, such as giving it the ability to spit out Markdown.
  • Sass/Less - Originally the sites style was built with less which extended an underlying Bootstrap dependency. Now that Browsers almost universally support more advanced layout rules such as css-grid the CSS is minimally written to support a basic layout - I use Sass to provide a few utility methods
  • Vanilla Javascript - as little as possible. No transpilation, no typing (don't love this), just a tiny amount of Javascript to try to be clever with the logo, decrypt blog posts and load/cache content fast

All of these are managed through Javascript build scripts which are invoked through an NPM package.json. I run npm run build and in about 2 seconds the whole site is rebuilt. I'm always telling myself at some point I'll actually build a clever watch script which actually will just rebuild the part which changed, but that very low on the priority list.

Fun Bits

Since I wrote the build scripts and implemented the basic framework myself adding new features doesn't feel like a terribly heavy lift. Some of the things I have added

  • Encrypted Filter - When I set a :encrypted <password> section around a chunk of HTML in pug it will use SJCL to encrypt the content. The website is deployed with encrypted hash living as a Javascript variable set inlined in the page. When the webpage contains the password in the hash of the URL the content is decrypted and displayed. As the code for getting password from the hash is also inlined the password is immediately removed from the URL. Also supports a "max reads" variable if you want the webpage only readable "X" number of times. Has flaws, but clever for a clientside approach
  • Image hashing with blurhash - I wanted the pages to load as fast as possible and lazy load images so I wrote a Pug processing function that will take any images inlined and create the corresponding blurhash which is inlined on the page - the actual image is then loaded when detected on the page
  • Generation of HTML chunks - if certain pages share the same layout, the code that generates HTML for each page and will then load only that HTML asynchronously instead of reloading the whole page
  • Lazy loading HTML chunks - an extension of the above, after the page is loaded and is idle the rest of the pages across the entire site will be loaded/cached in the browser
  • Purge CSS - I use a tool called PurgeCSS to remove any unused CSS from the site. This is done as a build step and is a great way to keep the CSS as small as possible

Where it Deploys

This website deploys when it is pushed to Github. Cloudflare picks up the change, builds it and deploys the new version to it's worldwide CDN network. This costs me nothing. Cloudflare pages is a "pay per invocation" and as the site is wholly static no code is ever invoked.