I chose Hugo

Table of Contents

It finally happened; I made a blog. I’ve been mostly procrastinating, but also contemplating for a long time whether I should create one or not. Whether what I have to say is worthy, whether it produces noise, or whether it produces value. Finally, I have decided that it is a challenge I want to take on, and just enjoy the journey.

This blog is bound to be drowned in the vastness of the internet and only end up useful for training LLMs. But, we’re not here for that defeatist attitude. Regardless, I don’t know of a more lightweight process to share the interesting bits from personal projects, and really, what the main challenge is, practice writing. So, here I go. Please, bear with me.

Another blog - how cliche…

The first choice I have to make is whether to build my own platform or choose an existing one. Building my own sounds way more fun, but then I would probably never end up with a blog. So I will have to settle for the next best thing: using an existing open-source platform. Let’s list some requirements.

  • I must be able to write using my editor.
  • It must allow text-based formatting.
  • It must support static site generation.
  • It must be Git based.

No WYSIWYGs

WYSIWYG is an acronym for what you see is what you get, and such editors just don’t work for me. It is like they are asking me to fiddle with formatting options. This is completely detrimental to my flow. I absolutely need least amount of friction when writing as I seem to be motivated to find an excuse to stop.

That isn’t to say that they are not useful or that they don’t have any strengths; they just don’t work for me. Since I am the benevolent dictator of my blog, no WYSIWYG will be allowed! Rant over. What I was trying to say, was that I should be able to write using my preferred tools. My preferred tool is my text editor and not some web-based monstrosity forced tool bundled with the platform.

Since my editor is just a text editor, then I must be able to format the text in the article using a markup language. I think Markdown will do. Researching for the perfect markup language is not something I am willing to do right now. After all, I have to start writing a blog post or this wouldn’t be much of a blog at all.

Justice for Web 1.0

I sometimes reminisce about simpler times when HTTP was for hypertext and web content was produced and enjoyed at leisure speed. When not everything had to be commented on, or re-tweeted (re-xed?), or liked, or subscribed to… You get the point. This blog will not contribute to the insanity complexities of today’s internet, and will instead show appreciation for the simpler times. No ads, no affiliate links, no commenting, no liking, no social media, no invasive tracking… Just musings and plain-old static content. Web 1.0 is fast, simple, and user-friendly. It deserves to live. So static site generator it is.

GitOps

GitOps is awesome! I say that even though I am not quite sure what GitOps is exactly. The common denominator definition seems to be something like this.

GitOps is a process or a set of practices where a Git repository serves as the source of truth. Changes to the repository result in an update to the system so as to reflect the current description in the Git repository.

Ok, that ended up being a mouthful. Let’s try again.

Git stores definition; change to definition updates system.

There, that should be succinct. I like that process, and I want my blog to work like that. I write, I commit, I push, I see blog post. Simple, and it allows me to never even leave my preferred writing tool, my editor.

The choice

And the winner is, drumroll… Hugo! I did a quick internet search for my options and with Hugo I saw what I needed to see. I like Go, I like Markdown, I like static site generators, I like GitOps. Maybe there are better options but I didn’t see any red flags and there is no time to waste. We have to focus on main challenge, practice writing.

Ok, now what?

According to the quick start guide we have to generate a new site.

hugo new site <site_name>

Easy enough, if have already installed Hugo. So the next step is to install a theme. But, do I have to install one? Let’s see if it works without one… And sadly, it does not. Even running

hugo new theme <theme_name>

does not seem to be minimal code to see the website. That is a little odd. We can look into creating minimal theme later, but for now we will follow the guide and find a theme. There are quite a few neat looking ones, but I think I will start with hugoplate. Feature rich, clean, has dark and light themes, and is using tailwindcss. Should be a great example to get us started. I’m sure we’ll learn a lot from it, but we’ll probably have to modify it.

According to the documentation I should add a theme by running git submodule add..., aaaand I see nothing. Ah, so the theme expects us to follow a different procedure to get started. I am starting to see a theme 😉 with Hugo guides. Flexibility is a double-edged sword.

I see that figuring out what is standard Hugo and what is a theme-provided feature will be a journey, but I’m already too deep in the sunk cost to turn back now.

Another subtitle

So there is something called front matters, I wonder what that is. Oh, neat! So it is a post metadata that can do all kinds of things… Like these tags, and categories?

I think we will also need a menu. Looks like in order to add it, I have to change the config. I think I will have a home page, and an about page

[menus]
  [[menus.main]]
    name = 'Home'
    pageRef = '/'
    weight = 10
  [[menus.main]]
    name = 'About'
    pageRef = '/about'
    weight = 20

Aaaand, it does not work. Why? Looks like the theme is handling it differently. Another theme base deviation, looks like this is a thing in the theme world.

This would not be a tech blog without code blocks. So let’s try that. After a little digging through syntax highlighting docs. I think that if I add

```go {hl_lines=[2]}
func main() {
	fmt.Println("Hello World!")
}
```

and if I’ve done everything correctly, it should then turn into…

func main() {
	fmt.Println("Hello World!")
}

E voila! Code blocks work! You can even highlight some lines, thanks Hugo!

Tip

To achieve ``` in code fences I had to wrap it in ```` (4 backticks). Does it work with 5?

````markdown
```go {hl_lines=[2]}
func main() {
	fmt.Println("Hello World!")
}
```
````

It does, TIL!

How to do homepage and pages

uglyURLs, ah yes, an address ending in .html a reminder of the simpler times, when HTTP used to be for hypertext and PHP used to be known as Personal Home Page.

Functions, slices after

Build

Ok, let’s build. So just run hugo, huh? Well, that was simple. Now I have a directory full of static files, yay! Exactly how I wanted it. Thanks Hugo! Now to address the small issue of serving these stat files. I think, I think… I will try Caddy. Written in Go, has native Let’s Encrypt support, what’s not to like.

Tags: