How to Publish Your Website with Hugo and Netlify

9 minute read #hugo #netlify

This is a post explaining how I setup my website using Hugo and Netlify, and a complete step-by-step walkthrough about how you can do it too.

Picking the right tools #

Prerequisites #

Hugo #

Hugo is an open source static site generator for building blogs and websites.

There are blogging platforms like blogger.com, which I did use before, but this time I wanted to make my own website, and have full control over the output. And I wanted to get started as soon as possible, and Hugo allowed me focus on writing (it’s not true, I couldn’t resist tweaking the theme here and there).

Why Hugo? Hugo is a fast, flexible, simple yet powerful website builder. You write your website content in a text file, and get static HTML output you can host anywhere β€” be it S3, Firebase, Github Pages, Netlify, or any webserver for that matter.

Netlify #

Netlify is a platform for building Jamstack web apps. You don’t have to know what Jamstack is to start building your website. You can get started on Netlify without a credit card.

Why Netlify? I considered Firebase and Github Pages before settling on Netlify. Firebase was a complete set of tools and felt overblown, and Github Pages simply didn’t allow me to publish from a private repository (I’d like to keep my drafts private please).

And Netlify had a simpler goal: Publishing JAMStack websites. It can build your Hugo website for you, so you don’t need to build and copy the static output yourself. All you need to do is write your post (once you’ve set it up properly), push to your git repository and Netlify will trigger a new build with your updates. We’ll go over it in detail below.

Setting up Hugo #

On a Mac, you can use Homebrew to install Hugo:

brew install hugo

You can find thehugo package available on popular package managers like Debian’s apt-get, Arch Linux’s pacman, Windows’s choco. If you need help installing Hugo, please see the complete install guide.

After installing let’s check which version was installed:

$ hugo version
Hugo Static Site Generator v0.72.0/extended darwin/amd64 BuildDate: unknown

The version number might be useful later.

Create a new website #

Let’s create the website now. When you invoke the following command you’ll get a skeleton website with default settings, and no content.

$ hugo new site hello-hugo
Congratulations! Your new Hugo site is created in /Users/dulguun/source/hello-hugo.

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from https://themes.gohugo.io/ or
   create your own with the "hugo new theme <THEMENAME>" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
3. Start the built-in live server via "hugo server".

Visit https://gohugo.io/ for quickstart guide and full documentation.

Let’s take a moment to start tracking the changes in a Git repository.

git init
git add .
git commit -m 'start my website'

As the message says, you need to pick or create your very first theme. Making a theme is another game, so let’s pick one from themes.gohugo.io for today. You can browse the rich gallery of themes and actually spend an hour doing it! πŸ˜…For the purpose of this post, let’s go with Anubis, a clean, and minimal theme.

When it comes to adding a theme to your site, there are two ways.

  1. Add the theme repository as a Git submodule
  2. Copy the theme content as files

Option 2 is suitable for you if you’re thinking of modifying a theme and adapting for yourself. Let’s go with option 1 today. You can come back to theming later, add and try as many themes as you’d like.

$ git submodule add https://github.com/mitrichius/hugo-theme-anubis.git themes/anubis

After adding the theme, modify your site configuration (config.toml) so that it knows which theme we’re using. While you’re there, feel free to give your site a new title, and set the base URL to a relative / (we can change it to an actual domain later).

baseURL = "/"
languageCode = "en-us"
title = "My New Hugo Site"
theme = "anubis"

Now we’re ready to start the server!

$ hugo server -D

                   | EN  
-------------------+-----
  Pages            |  9  
  Paginator pages  |  0  
  Non-page files   |  1  
  Static files     |  1  
  Processed images |  0  
  Aliases          |  1  
  Sitemaps         |  1  
  Cleaned          |  0  

Built in 16 ms
Watching for changes in /Users/dulguun/source/hello-hugo/{archetypes,content,data,layouts,static,themes}
Watching for config changes in /Users/dulguun/source/hello-hugo/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Let’s go to http://localhost:1313/ in your browser:

Empty front page.

Now that’s one blank slate! All we’re missing is the content.

Write your first post #

Let’s create our first post now:

$ hugo new post/new-post.md
/Users/dulguun/source/hello-hugo/content/post/new-post.md created

Open up the newly created Markdown file in your favorite editor and write you first post:

---
title: "New Post"
date: 2020-06-13T13:33:18+02:00
draft: false
---

Hello Hugo!

The post will have a draft: true flag, set it to false or remove the property completely (although hugo server -D shows you draft previews, we want to set it to published for when we later deploy on Netlify).

While keeping the hugo server -D running, save the file, and you’ll see the website updated live on the browser! ✨

First post is visible.

Congrats! πŸ™ŒπŸΌ You’re well on your way to publish your website online! 🌐

Coffee break β˜• #

That was kinda lot. Let’s take a short coffee break.

Clip of red pandas wandering around. I played this clip like 10 times while writing this.

Generate static output for publishing #

You may not know where to go from there, and how the whole website should be structured. Hugo themes come with an example site content you can peek into. Go to themes/anubis/exampleSite to learn how it was organized. Each theme may have different configuration options, so don’t forget to look into its config.toml too.

Let’s take a quick look at how to generate the static output with Hugo. This is not necessary with Netlify, because it’ll take care of it for you.

The following command will generate your static website to the ./public directory:

$ hugo -D

                   | EN  
-------------------+-----
  Pages            |  9  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  1  
  Processed images |  0  
  Aliases          |  1  
  Sitemaps         |  1  
  Cleaned          |  0  

Total in 24 ms

The public directory contains the final result:

$ tree public 
public
β”œβ”€β”€ categories
β”‚   β”œβ”€β”€ index.html
β”‚   └── index.xml
β”œβ”€β”€ css
β”‚   └── style.css
β”œβ”€β”€ index.html
β”œβ”€β”€ index.xml
β”œβ”€β”€ page
β”‚   └── 1
β”‚       └── index.html
β”œβ”€β”€ post
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ index.xml
β”‚   └── new-post
β”‚       └── index.html
β”œβ”€β”€ sitemap.xml
└── tags
    β”œβ”€β”€ index.html
    └── index.xml

7 directories, 12 files

Now, you can of course build your site manually like we just did, and copy the output to some server yourself. In the next section, we’ll see how we can automate this publishing process with Netlify.

Sync your changes to GitHub #

Before we move on, let’s push the changes to GitHub. Netlify will read from this repository and publish the website.

First, create an empty repository on GitHub. It can be either public or private.

Since we already have a local repository with history, let’s add the new one as origin, and push to it.

We don’t need to track the generated public directory, so let’s ignore that in Git.

$ git remote add origin git@github.com:dolugen/hello-hugo.git
$ echo 'public/' >> .gitignore
$ git add .
$ git commit -m 'wrote my first post!'
$ git push -u origin master

Setting up Netlify #

First, signup to Netlify.com. It’s free to get started, and the free plan should be enough for your personal website and other hobby projects.

After logging in, go ahead and click on the “New site from Git” button.

Netlify's empty overview screen

On the next page, clicking on “GitHub” will open a window that will authorize Netlify to access your public and private repositories.

Netlify's create new site screen

In the next page, select your Hugo website repository:

Netlify's pick a repository screen

Once selected the repository, configure the deployment:

If all looks good, click “Deploy site”.

Netlify's deploy preview screen

After that your site should start deploying immediately:

Netlify's building the site screen

⚠️ Now, your first deploy may fail. This happened to me couple of times too. The trick was to specify which Hugo version to use in a netlify.toml file. Let’s add that to our repository (your installed version may differ) :

[context.production.environment]
HUGO_VERSION = "0.72.0"

And commit and push that change to GitHub. Netlify will see that there was an update and build again:

Netlify's last build says 'Published'

Let’s checkout the live site:

The website is live

It works! πŸš€

Add a domain #

Now that you have the content sorted out, let’s add a domain. Netlify’s onboarding experience is pretty smooth that it’s displayed prominently on your website overview page:

Netlify's Getting Started workflow

You can buy a domain from sites like namecheap.com. You can buy one directly from Netlify too. Go ahead and pick a domain, I’ll wait.

If getting a domain is not possible for you right now, that’s OK. You can still keep writing on the *.netlify.app domain for now, and do the domain work later on.

Netlify's DNS settings

After buying and adding the domain to Netlify, you need to do a bit of DNS dance to prove yourself you’re the owner of the domain. I’ll let you figure that out yourself, since you were able to come this far. For me, I went with Netlify DNS, where Netlify manages the whole domain for me.

Once your domain’s setup, Netlify can enable HTTPS for your domain, so that you can have nice https://example.com URL. I didn’t need to do anything, as it was enabled automatically for me.

Conclusion #

Both Hugo and Netlify offer rich customizations, but for now I think we have enough to keep publishing our first posts.

Hugo lets you tailor your website to your heart’s content, and Netlify can make your static website dynamic with forms and functions! But something tells me I don’t need those just yet. I may visit them in future posts if I implement the extra features.