Tag Archives: jekyll

Elementary Theme For Jekyll

It is hardly ever the case that I work on a single side project for years, a sentiment that my fellow software developers might share with me. This blog that you’re reading this article on is one such rare project. And although there have been crests and troughs in terms of my activity here, it has been fairly consistent, especially considering my reputation of abandoning projects.

Anyway. Where I was going with all that blabber was that this template that you’re reading this on is already two years old now, and I recently rolled out an update that I was pretty proud of. In this little post, I’d like to outline in brief how I reached the current version of this template and why I’m super happy with the outcome.

Backstory

I created the template by simply removing as many unnecessary parts of my then current template as possible and making it a simple, one request only template. It was essentially a blank HTML page with few lines of CSS, no JavaScript, default browser font and styles. Of course, it was blazingly fast but also quite ugly. I went to the extreme end of the spectrum as my starting point.

Slowly, I added stuff to it, on a strictly per-requirement basis. More CSS, some JavaScript, introduced SCSS to make the CSS maintainable, made the JavaScript optional as not everyone needs a dark mode and so on. I made the project installable via git submodule so that it is easy to customize it and at the same time pull updates from upstream.

Current status

It feels good to not trigger advertisement and tracker blocking tools like uBlock Origin. And by not loading hundreds of kilobytes of minified code that contains trackers, suboptimized routines and who knows what, I’m also being fair to my visitors who, when you think about it, trust you as the web developer by loading and executing your code on their machines.

On a more objective side of things, here are a couple of features (copied over from the project’s github readme) I’m super happy to announce:

  • Lightweight, <10KB CSS, <3KB (optional) JavaScript + 15KB Open Sans font file + your content. That's less than 40KB transferred for most pages
  • Highly accessible with semantic HTML
  • Structured data (schema.org) pre-added for blog posts
  • Dark mode (requires JavaScript for toggling class and saving user preference in cookies)
  • Reading progress slider on top (requires JavaScript)
  • JavaScript is optional (turn it off in _config.yml)
  • No request made to any third party
  • Installable as a git submodule

Try the project here: https://elementary-jekyll.github.io/. Below is a picture collage of interesting observations about the theme.


Picture showing 100 score on Google Page Speed, <1 second median load time, 100% cached on Cloudflare and a screenshot of the template running on Kindle
Picture showing 100 score on Google Page Speed, <1 second median load time, 100% cached on Cloudflare and a screenshot of the template running on Kindle. Mobile users can click on the image.

Here’s what the dark mode toggle looks like.

Dark mode demonstration

And this is the scroll progress indicator

Reading time indicator

Todo and future

I’m probably not going to give up on this template just yet. But I really want to move away from Jekyll now. No, I don’t dislike it. It is probably perfect if you just want to focus on writing as a person who doesn’t mind using text editors and the terminal. I just want to be able to dig into the source code of the build tool, the configuration files, write a plugin myself, be more comfortable with the whole ecosystem in general. To do that, it is important that I move to a tool that’s written in a language I know, or want to learn. Jekyll, and hence Ruby, just isn’t either of those.

If you’re thinking of starting a blog, or moving to a new template and see this one a good fit for your taste, do give it a shot. In case you actually end up using it, please write to me. Of course, it is open source and GPLv3 licensed. In the future, if I manage to move my blog elsewhere, I’ll port this template to the new system.

I remember wanting to have a simple static site generator after having struggled with tools like WordPress and Blogspot for this blog. I’ve reached a point where I feel like I need some of that complexity back. Guess I’ve reached the other side of the sine curve!

Thank you for reading.

Search On Jekyll Blogs

Static site generators are great. No fuss, pure purpose. I use Jekyll because that’s what Github supports the best. But these days, with services like Netlify, you have many options. This site aggregates the top ones, so give it a look if you’re planning on setting up one for yourself.

staticgen.com is a nice website to find a static site generator right for you

One thing that’s tricky with static site generators is search functionality. Since there’s no backend, whatever you plan on searching has to be generated the same way other content is. Often, that means iterating over all posts and creating a json file which you can fetch in the frontend and do offline search.

While that works, it doesn’t give you full content search (if you include content in that json blob, it will grow in size and get slower with each new post). But full content search is exactly what you need at times. I needed content search, and I spent sometime researching the options that exist. Below, I’ll list a couple of them, not necessarily only the ones that offer full content search but each suited to some specific use case.

Netlify Functions

Netlify has managed cloud functions thingy (serverless) and it works on top of AWS Lambda. It is very simple to write a function with netlify, and when you push your code, the functions are deployed as well. It comes with a free tier which runs on a 128mb instance. Pretty low, and would time out in 10 seconds if you give it a lot of work.

Netlify picks functions from a directory and pushes them to aws internally. Now, we need our json file to be present in Netlify lambdas directory before the push happens. We can make use of a simple node module Front Matter that would take our _posts directory and return a nice json with frontmatter and body parsed. Then we take this json and write it to a file which we can then import from our lambda function.

Now, for the search function, we can use something like FlexSearch that does offline searching. Just that we’ll use it in the lambda.

And you should update your build command in netlify’s netlify.toml file (or web interface) to run the node script before the jekyll build step.

  $ npm run create-json && jekyll build

Keep in mind that the free tier is very low-duty. Try to strip down content by filtering stopwords and doing other optimizations.

On the frontend, you make a GET request with query parameter q to this endpoint like you would with a regular backend search.

Algolia (or any search as a service)

I’d start with stating why Algolia didn’t fit very well for my use case. Their record (think each individual post text plus metadata) size limit is 10kb, so if your content is frequently more than that, and you want it to be searchable, Algolia might not be the best for you. But if you don’t need full content search, or if you write little posts that are usually less than 10kb, it might be a good option to look into.

Essentially, you create a searchable index on Algolia (simply upload a json file or use their jekyll-algolia gem), and use their client side libraries to query this index. They have a nice and simple web interface to do it manually or just use a script to automate it via their APIs.

Like mentioned before, you can implement a two step deploy process to Algolia that removes stopwords and duplicate words from the text before pushing the index. That way you can still fit the record in 10kb.

AWS Lambda

Netlify search uses AWS Lambda internally, but netlify only offers a couple of tiers ($0, $25 and a custom plan for $500 paying customers). On the other hand, AWS has a wide variety of lambda instance sizes and charge per usage which makes it super cheap.

What you lose in this case (compared to Netlify functions) is that you have to set up the CI pipeline yourself from scratch. So no automated pushing of the functions along with your static site. If you have a lot of searches, or heavy search queries, AWS Lambda is the way to go. For very simple and light weight use cases, Netlify isn’t a bad choice. Note that Netlify also deploys to AWS, so your function will work on either service with little to no modifications.

ElasticSearch

This is a complex solution when compared to the others on this list. Essentially you create a simple app on, say Heroku with a simple GET and POST interface. You can pair this app with a free Bonsai ElasticSearch instance. The POST will push data to this instance and GET will fetch search results.

The middleware Heroku app is to simple prevent our Bonsai credentials from getting into the wild. I didn’t think this was a good solution for simple use cases because of the maintenance factor. The reason we use Jekyll (or any static site generator) is to keep things simple, and this search solution is hard to sell to people like us.

In closing

As I found out, there are many ways of implementing a good search feature on a Jekyll (or any statically generated site). I’ve left out details of the implementation as I couldn’t find time to do so but what I learned was that just knowing that these options exist helps a lot. So the next time I’m thinking, “hmm, I’d like to have a search here, but not sure how to handle the logistics that come with it”, I’d already have a few options!

Thank you for reading.