Note: This post is availible as a YouTube video. Check it out!
After months of on-and-off work, version 8 my personal website is finally done. Less done and more that I’ll stop working on it, but still. Before I start work on FG X (the 10th redesign), I thought I’d summarize some of the features I’ve added.
New Design (Including Dark Mode!)
The most noticeable change in v8 is the theme. I’ve wanted this design ever since 2017 taking cues from Cal Newport’s old website, but I only added it in January of 2019.
Honestly, the design is boring. Even after spending hours trying to nail the color scheme for the links, it isn’t special. Even worse are all the noticeable usability issues, like the links in the footer being too small and close together.
While my implementation works, saving eyes and mitigating climate change since displays (well, just OLEDs) use less power, it’s a bad implementation. It’s ugly and it’s poorly coded given the excessive use of
!important. Worse still, there’s no way to disable it.
I thought it would be cool to add a search feature. I was planning to use Algolia, but the set up is overly complicated for a static website. I then wondered if there were front-end search libraries and it turns out there are.
I decided to use lunr.js because… honestly, I don’t know why I did. Maybe it’s because it was the first result to pop up on Google search? There are other options like Fuse, but I don’t know enough about them to make a good recommendation.
To use lunr, you need to build an index from the text you want to make searchable. In my case, this meant making a 500kb JSON object with every post’s content (HTML stripped and sanitized) which lunr.js will index. Using that index, it’s up to you to add the UI.
My UI is basic with a simple form that dynamically updates as the query is entered and lists the results. It’s no Google Search, but it’s a nice feature. It makes looking up older posts much easier.
My search page could be better. For one, I could add more granular search options like date ranges, categories and tags. It would also be nice to have better keyword highlighting, the search form appearing in the header or footer outside the search page and the ability to search by query parameters.
The page’s also accessibility needs some thought. I planned to add a lot of ARIA, but then I discovered the
output tag which does exactly what I want to do. Still, I need to test things.
I could also improve performance by pre-building the index. It was mentioned in lunr’s documentation, but I didn’t do it because there’s a lot of set up needed as I’m using Hugo.
There has been a revival of RSS (among tech nerds anyway) given how algorithmically-driven social media sites are acting like jerks. To hop on this trend, I decided to implement my own RSS feed in Hugo. I got lazy when it came to organizing content properly so I made one big RSS feed at /index.xml.
It wasn’t as simple as using the right template tags. Rather, there were many little quirks that frustrated me. Plain text is boring, so I used HTML. Turns out that HTML conflicts with the XML used in the RSS field file. Fine, I’ll escape it. For some reason, the escaped HTML got escaped again. No worries; I’ll escape it using
<![CDATA[...]>. Didn’t work. Why? Well, Go’s templating engine is trying to protect me from nasty code injection. Some very cautious escaping later, it worked.
The feed looked decent except for all the validation errors. They’re technically recommendations now, but there were loads of errors. For one, the dates are in the wrong format. I thought it was right, but it wasn’t. Secondly, the images have to be abolute URLs, not relative ones, so RSS readers can resolve them properly. I fixed it, albeit badly. Don’t care; ‘still works.
As for JSON feed, it wasn’t as bad as getting the RSS to work since Hugo escapes the HTML in the JSON. The biggest problem though was getting the id field right since I tried to increment the field. Figured it out eventually.
I’m scared of having comments on my blog so I’ve decided on adding an email link at the end of every article to get feedback? I did learn a lot about building an email link. Did you know that there’s more than just
mailto:email@example.com. You can add CC and BCC fields as well as the subject and body. This isn’t the best UI (a form is better) but I can’t afford a proper email relay.
Compression and Minification
To improve my website’s performance, I looked into reducing the code’s size. Minifying was simple since Hugo has a
--minify option. As for compressing the website, I had to get clever with GitLab CI so that it would only compress the text files (images don’t work well with compression).
I also found a service that compresses PNG files (which usually come from screenshots) which can reduce image sizes by as much as 90%. Most of that is because screenshots have an alpha channel that’s mostly uneccesary although there are some other compression techniques for PNGs, like indexing colors. It does need some tweaking to make sure the colors don’t look terrible.
Building Via CI
One benefit of GitLab over GitHub is that GitLab comes with CI. Using CI, you have much greater control over how to build your website. Instead of having a limited set of plugins you can use, CI lets you build your website however you wish. That’s how I compress the output files. Main drawback is that it can get very complicated.
Actually, just as I was writing this, I discovered that GitHub is woring ong GitHub Actions, their CI/CD platform. Ah well ¯\(ツ)/¯.
Not really a feature, but since it would be nice to make money and I don’t have any visa restrictions at the moment, why not? I haven’t earned a single dollar yet and I probably won’t for many more years, but it doesn’t hurt to ask.