Building My Personal Site with Zola and Tailwind: What I Learned

July 27, 2023

development, zola

I recently used Zola and Tailwind to rebuild my personal website and blog. I'd like to share my development experience and some of the things I learned along the way.

My situation

About 5 years ago, I started out with a small Jekyll blog on github where I did "daily" blogging about things that I was learning each day. That was something I kept up with for nearly a year and a half before burning out. Along the way (and after getting on the go train), I came across Hugo and underwent the process of migrating my blog from Jekyll to Hugo. And that was the last I touched my blog for nearly 2 years.

During that time I had also created two different portfolio sites: one that was a glorified splash page to point people to my other sites, and the other a showcase (hosted on github) of some of the personal projects I've worked on. That meant I had my projects, thoughts and identity spread out in multiple places.

When I recently decided I wanted to get back into writing again, I had to decide how to approach this problem. I could continue using the split websites I had, or I could look to unify everything into a central location. Ultimately I landed on the decision to create a new "portfolio" site where everything can be easily accessed and maintained.

Why Zola?

Prior to this project, I had zero experience or exposure to Zola or it's templating engine Tera. So why would I pick it for my project?

The short answer is that I simply wanted to learn something new.

The long answer is that I knew I wanted to use a SSG to make the site as light as possible. I wanted to make something that was stupid easy to maintain. I wanted something that I had control over.

I knew from the beginning that I was going to be creating my own theme for my site, so the lack of available Zola themes was not a turn off to me. If I was going to go with a pre-baked theme, I would have stuck with Hugo. But truthfully, I never understood how Hugo worked. The templates for the themes I'd tried were overly complicated, fragile, and frankly, terrifying to touch. "What is even in these files?", I would ask myself.

So I wanted to start from scratch. I wanted to understand how my site was built. I wanted it to be dumb. It also needed to be able to source from .md files, as had originally planned to suck in my existing blog posts.

Admittedly, none of those reasons are uniquely solved by Zola. It just happened to be a "new" tool that handled them all. Also Rust.

Why tailwind?

I have previously used tailwind on one project, and that was my old "splash" personal site. I wouldn't describe the process as being enjoyable.

Since creating that site, I went on to make many (many) sites using the Bulma framework. While it made it super easy to get up decent looking websites, I wanted to have a little more control. After all, this was for my personal site.

So I decided that rather than using a library with pre-defined components, I'd try to roll my own along with using Zolas templating engine for reuse. How hard could it be?

The initial wall

Over the years, I have learned (and re-learned) one specific lesson when it comes to projects - pick one thing new. In this case, I had two new things. The Zola piece was easy enough. They provide a tutorial for getting started that does a good job of explaining how the pieces connect. By the end of it, you have a good idea of what's going on.

However, when it came time to building the components for the site, I quickly realized I had no real sense of UX design. I quickly understood just how reliant I had been on frameworks dictating the feel for me, I literally never had to think about it.

I ended up going down a rabbit hole of looking for tailwind examples or snippets that I could take from and start building what I needed. This only increased my resentment, almost pushing me to the point of dropping tailwind for bootstrap. It was "too hard" and I just "didn't get it".

Eventually I forced myself to sit down and just play around with it. After some hours of fiddling around, I was at least at a point where I could start working on the site.

Breaking things down

Zola and Tera allow for you to break your pages down into reusable pieces, in the form of partials and macros.

Partials are great when you have a static component that needs to be reused. Something like a header, footer, or a component that doesn't change. An example of that would be the card system I use on this site. I'm able to pull in all of the pages from a specific section and then pass that data straight into the partial. For example:

{% set ssection_data = get_section(path='blog/_index.md') %}
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 xl:gap-10 justify-items-center">
  {% for page in ssection_data.pages | slice(end=3) %}
	{% include "partials/blog_card.html" %}
  {% endfor %}
</div>

Macros are similar to this, only they allow you direct control over what gets passed in. Once a macro has been added, you can call it with your values:

{{ macros::icon(link="https://www.twitter.com/", title="twitter", viewbox="0 0 1024 1024", path="...") }}

It's a pretty straight forward system, and I spent a lot of time abstracting components into macros... only to realize that it breaks tailwind.

The way that tailwind works is that it steps through your code to see what classes you're actually using, and then builds your css file with them. And that's great, when your styles are actually using their real names. But by abstracting into macros, I effectively broke this, and tailwind no longer generated what I needed it to.

I spend a bit of time looking into how to handle this, and ultimately walked back my macros. There may have been a way to run this "post build", but I really didn't want to alter the current dev experience of having both Zola and tailwind running in --watch mode as I worked. So I took the easy way out. Just be aware of this up front (pretty obvious in hindsight).

Debugging build issues

Tera is written in rust, which means that everything has to be correct for your site to build. If anything is wrong, you're going to get yelled at. So expect to be seeing a lot of red in your terminal telling you that things are broken.

Initially when I started to write this section, I was going to say "blah blah unhelpful messages blah blah". But in looking back over the errors/warnings that Zola produced, they were basically always helpful. Take a look at this one from the end of my development:

Error: Failed to build the site
Error: Failed to render section '.../content/blog/_index.md'
Error: Reason: Failed to render 'blog.html' (error happened in 'base.html').
Error: Reason: Variable `page.title` not found in context while rendering 'blog.html'

It points you straight to the issue. I can't render the blog page because I'm trying to use a variable page.title that doesn't exist in the base.html.

Like a lot of things, it can be a bit overwhelming at the beginning, but those errors can really be your best friend. Read them, don't ignore what they say.

Getting things done

Here are some of the resources that helped me to get this project done in ~a week:

1. The kodomana theme

This is a Zola theme that also uses tailwind. While I didn't care for the template itself, I found the code in the templates to be immensely useful. Without some of the template examples there, I don't think I would have gotten partials or macros working.

2. The Tera documentation

Zola uses the Tera template engine, so be prepared to have this site up at all times until you've gotten used to it. A lot of the Zola documentation assumes you know Tera (or you know how to look it up), and leave out some vital details. Probably one of the most important things in the docs is how to print our your objects using json_encode(), which will let you see just what you're working with when the docs might otherwise be lacking.

3. The Zola documentation/tutorial

It should go without saying, but prepare to read the docs. The tutorial is great, and you should do it. Don't be afraid to search - most of what I ended up needing was in the docs, but it might not always be where you expect it to be.

4. Flowbite Tailwind examples

This site was great when I was having difficulty envisioning how a component would look or how to structure it. I didn't use the library (I think it's a library), but my cards were strongly based on the examples found on the site.

So, would I recommend Zola

Zola is a tool. It allowed me to accomplish the task that I wanted to achieve (making a simple blog like website), and should continue to be relatively hands off for the rest of my sites lifetime. For that I don't have anything bad to say.

The documentation took a bit of time to wrap my head around, and chatGPT was often completely wrong in guiding me to a solution, but I did eventually get there. As a result of the friction, I understand my implementation much better.

Again - nothing super unique to Zola. Plenty of other tools could have accomplished the job. But if you're looking for a SSG tool that works with markdown files and handles a lot of blog like things for you, Zola is a great tool for the job.