Liam Asman's Blog

Creating a simple blog with Hugo and Netlify

tutorial

-

I wanted to create a blog that would allow me to share posts on various topics and photography. Wordpress is a bit too heavy-weight for what I wanted, and I wanted to keep costs way down, preferably free, excluding the domain name.

Hugo is a static site generator that is fast, and has great support for image processing. Posts are written in Markdown as individual text files and converted to HTML as a build step in a CI pipeline. Hugo also supports RSS, a small nerdy feature that I wanted to have.

While I don’t mind paying for hosting, I wanted to keep costs down. I don’t expect a lot of traffic, so for now the free tier of Netlify is perfectly capable of hosting the site.

Posts are committed to a GitHub repository, and Netlify will automatically build the site and deploy it to the web.

The following are the steps I took to set up the blog, including custom HTML and CSS. I use Cloudflare for DNS for my domain, so will also briefly cover the DNS configuration to point the domain to Netlify.

Initial Set Up

1. Install Hugo

While not strictly necessary, I recommend installing Hugo on your local machine so you can preview your changes before pushing them to GitHub. It also makes setting up the skeleton of the site easier.

You can find instructions for installing on your system at

https://gohugo.io/installation/

2. Create a new site and git repository

hugo new site my-blog
cd my-blog
git init

Find hugo.toml in the root directory. There are some basic configuration options that need filling in.

3. Add a theme

Find a theme you like. A list of themes can be found at https://themes.gohugo.io/.

Add it to your website as a git submodule, and reference it in the hugo.toml file.

git submodule add https://github.com/clente/hugo-bearcub themes/hugo-bearcub
echo 'theme = "hugo-bearcub"' >> hugo.toml

4. Run Locally

hugo server -D

This will start a local web server on port 1313. You can view the site at http://localhost:1313. The -D flag means draft posts will be included in the output.

Hugo will automatically re-build the site as you make changes.

5. npm install hugo

In order for Netlify to build the site, you need to install Hugo as a dependency in package.json. We can use npm to do this for us.

npm install hugo-bin --save-dev

6. Create a GitHub repository and push to git

git add .
git remote add origin git@github.com:my-user/my-blog.git
git remote set-url origin git@github.com:my-user/my-blog.git
git push -u origin main

7. Create a Netlify account and set up the site

Netlify is pretty straight-forward to use. Use ‘Import and Existing Project’, choose GitHub, and select the GitHub repository you just created. You should be able to leave most of the settings as they are, but just in case:

Branch to deploy: main
Base directory:
Build command: hugo
Publish directory: public
Function directory: netlify/functions

8. Set up a custom domain

Netlify has instructions for setting up a custom domain to point to the website. They refer to using a ‘flattened CNAME’. In cloudflare, this is a standard CNAME record. Cloudlfare will automatically do the flattening for you.

Ensure you disable Cloudflare’s proxy for the DNS record; Netlify has its own CDN, we do not need to run Cloudflare’s on top. It would only harm performance.

Customising the theme

I liked the look of the hugo-bearblog theme, however there were a few changes I wanted to make.

First, I wanted the home page to be a list of all my blog post titles. As my site evolves and I add more content, I may want to change this, but for the beginning I wanted the site to be extremely simple. Home page -> Blog post.

This meant overriding index.html, and removing the navigation bar by overriding nav.html.

Second, I wanted to modify the layout of the titles as they are listed. In particular, I wanted to add the category of the blog post to the listing.

Finally, I wanted to add a favicon.

We can achieve this with the following files:

layouts/index.html

{{ define "main" }}
<div class="home">
    <div class="posts">
        <ul class="blog-posts">
            {{ range where .Site.RegularPages "Section" "blog" }}
            <li>
                <span class="post-list-item-date">
                    <time datetime='{{ .Date.Format "2006-01-02" }}'>
                        {{ .Date.Format (default "02 Jan, 2006" .Site.Params.dateFormat) }}
                    </time>
                </span>
                <span class="post-list-item-title">
                    <a href="{{ .Permalink }}">{{ .Title }}</a>
                </span>
                <span class="post-list-item-category">
                {{ .Params.category }}
                </span>
            </li>
            {{ else }}
            <p>No posts yet!</p>
            {{ end }}
        </ul>
    </div>
</div>
{{ end }}

layouts/partials/nav.html

<!-- This file is intentionally left blank -->

assets/css/style.css

ul.blog-posts li .post-list-item-category {
    flex-grow: 1;
}

ul.blog-posts li .post-list-item-title {
    flex-grow: 4;
}

layouts/partials/custom_head.html

{{ $style := resources.Get "css/style.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
<link rel="icon" href="/favicon.ico" type="image/x-icon" />

Place your favicon icon in static/favicon.ico

Commit and push to GitHub. Netlify will automatically build the site and deploy it.

Congratulations!

#how-to #blog #technology