Rewriting My Personal Site with Hugo
Tags: webdev, go
Published: 2019-03-04 15:33:50

---
title: Rewriting My Personal Site with Hugo
published: true
description: How I rewrote my personal site with Hugo in one day
tags: webdev, go
canonical_url: https://andrewdavis.me/post/rewriting-my-personal-site-with-hugo/
---
A couple months ago I created my personal website called [andrewdavis.me](https://andrewdavis.me). I built it as a custom server side app in Go with MySQL holding the content. I wrote about the experience in [Building My Personal Site with Go and TailwindCSS](https://andrewdavis.me/post/building-my-personal-site-with-go-and-tailwindcss/). I enjoyed the project, however, I recently wanted to make some SEO improvements and decided maintaining a custom app was more work than I wanted. I started looking at different static site generators and found [Hugo](https://gohugo.io/). It is a really fast site generator that uses Go templates for HTML and Markdown for content. Hugo is very flexible, but also easy to use so I was able to move my site to it in a single day! In fact, I open sourced the code so you can see it all [here on GitHub](https://github.com/restoreddev/me). Now, my site is served from HTML files on GitHub Pages, making it much faster at rendering. Here are a few reasons for why I liked Hugo so much and why you may enjoy using it for your next project.

## Easy to Install and Start a Project
Hugo is a simple binary that [can be installed](https://gohugo.io/getting-started/installing/) on any OS (I used Homebrew on MacOS `brew install hugo`). To start a new project, open a terminal and run `hugo new site blog`. Hugo will create a folder called `blog` and generate a project skeleton so you can start adding content. To start building templates, add a `_default` folder in the `layouts` directory. In there you can create a new file called `baseof.html` which will become the base template for all your pages. After that you can create an `index.html`, `list.html` and `single.html` template. The index template will be used for the homepage, the list template for any list pages and the single template for content pages.

Next, you can start adding Markdown in the content folder. You can create Markdown files like `post.md` or `post/index.md` which will create different paths: `/post.html` and `/post/` respectively. Each markdown file must have frontmatter, but it can be written in YAML, TOML, or JSON. I wrote mine in TOML, which makes a page look like this:
```markdown
+++
title = "My Blog Post"
date = "2019-03-01"
+++
The content of my blog post goes here.
```

To build the pages, you can run `hugo server` in your terminal and it will start a server for you to see the site at `localhost:1313`. The server will also automatically reload anytime you make changes to your content. Hugo takes the Markdown pages' content and builds them into individual HTML pages using the Go templates. In the template, the Markdown file will be injected using predefined variables so you can use `{{ .Title}}` and `{{ .Content }}` to indicate where the Markdown data should appear in the template.

Of course, there is a lot more to templating and content, which you can find in the [docs](https://gohugo.io/content-management/organization/). Hugo is very configurable and can do as little or as much as you need.

## Automatic Code Highlighting
On the previous iteration of my site, I used the [Prism.js](https://prismjs.com/) JavaScript library to enable code highlighting. It worked well, but all the styles are added client side, which is unnecessary work for the browser. Hugo uses a Go syntax highlighter called [Chroma](https://github.com/alecthomas/chroma) that will add the CSS to the HTML in the build process. To have it run on Markdown codeblocks, just add `pygmentsCodefences = true` in the `config.toml` in the root of your project. The `config.toml` file is the main configuration file used by Hugo when building the site.

## Integrated CSS Processing
I like to use PostCSS for my stylesheets and Hugo works with it easily. I just created a `package.json` with `postcss-cli` installed and my PostCSS plugins. Then, I created a `postcss.config.js` file (not required by Hugo, just what is necessary for PostCSS). Afterwards, I created a CSS file in the assets folder and then imported it into my `baseof.html` template using:
```html
{{ $css := resources.Get "site.v01.css" }}
{{ $style := $css | resources.PostCSS }}

<link rel="stylesheet" type="text/css" href="{{ $style.Permalink }}">
```
Now, when I build with Hugo, it will automatically compile my stylesheet and link to it in my base template.

## Easy Deployment
Hugo has multiple different ways to deploy a site. When you run `hugo` in the root of your project, it will build the files in a `public` folder. I just followed their guide for [deploying to GitHub](https://gohugo.io/hosting-and-deployment/hosting-on-github/) and created a `publish.sh` script that takes the contents of the public folder and commits it to a separate git branch. The deployment branch is then used by GitHub Pages to serve the files.

## Conclusion
I really like that Hugo is straight forward and does not require writing JavaScript to build a static site, like many other generators. Plus, I can now easily update templates and add more features using frontmatter variables without having to write much code. Generated HTML files allow me to not maintain a server setup, decreasing the amount of maintenance time to keep my site going. All in all, I count it as a successful move and plan to use [Hugo](https://gohugo.io/) in the future!