How to host a Hugo site on the Netlify CDN for free

Hosting a Hugo site on Netlify is free (and awesome) if it’s a personal website. Here’s how to set it up and deploy.

Ron Erdos
Updated November 20, 2022
Tested with Hugo version 0.106.0

In this tutorial, I’ll show you how to get your Hugo site hosted on Netlify.

Hosting is free for personal websites.

Let’s dive in!

How to set up a Hugo site on Netlify hosting

Step 1: Sign up for Netlify

If you haven’t already, you can sign up for Netlify here.

I don’t make any money from this; I just recommend tools and services that I myself use and enjoy.

Step 2: Add your domain name to Netlify

2a) Log in to your Netlify account if you haven’t already.

2b) Head to the “Domains” tab.

2c) Click the “Add or register domain” button:

DomainsAdd or register domainSitesBuildsMembersAudit logTeam settingsDomains

2d) Add your domain name (or intended domain name—you can have Netlify purchase it for you).

2e) Hit the green “Verify” button:

Add a domain to Netlify DNSAutomatically provision DNS records and wildcard certificates for all subdomains.1. Choose domain2. Add DNS records3. Activate Netlify DNSWhat domain would you like to use?You can bring a domain name that you already own, or buy a new one.Domainmoonbooth.com Verify

If you already own your domain, you’ll see the screen below. (If you don’t own your domain, and want Netlify to purchase it for you, this tutorial doesn’t cover that yet. I may add it in the future.)

2f) Hit the green “Yes, add domain” button:

1. Choose domain2. Add DNS records3. Activate Netlify DNSAutomatically provision DNS records and wildcard certificates for all subdomains.Add a domain to Netlify DNSWhat domain would you like to use?You can bring a domain name that you already own, or buy a new one.Domainmoonbooth.commoonbooth.com already has an owner. Is it you?Yes, add domainNo, try another

Next, you’ll see the screen below.

There’s no need at this stage to add DNS records.

You can always do this later, for example, if you want to set up MX records for email.

However, for now:

2g) Hit “Continue”

1. Choose domain2. Add DNS records3. Activate Netlify DNSAutomatically provision DNS records and wildcard certificates for all subdomains.Add a domain to Netlify DNSAdd DNS records (optional)The DNS records for your Netlify sites will be configured automatically.Are you using your domain for other services, such as email? No problem! You canadd DNS records for those services at any time.ContinueLearn more about DNS records in the docsAdd new record

Finally, you’ll see the screen below. Keep it open in your browser as you’ll need it in a second.

1. Choose domain2. Add DNS records3. Activate Netlify DNSAutomatically provision DNS records and wildcard certificates for all subdomains.Add a domain to Netlify DNSUpdate your domain’s nameserversLast step! Log in to your domain provider and change your nameservers to the following:Donedns1.p04.nsone.netdns2.p04.nsone.netdns3.p04.nsone.netdns4.p04.nsone.net

Step 3: Log in to your domain registrar and update the nameservers

Every domain registrar’s interface is generally a bit different, so I won’t provide a screenshot here.

However, it should be relatively straightforward to find out how to change the nameservers for your domains at your provider (e.g. NameCheap, GoDaddy, VentraIP etc).

You’ll need to update the nameservers to the ones you got in the previous step of this tutorial—which may be different to the ones in my screenshot above.

Once you have made these changes, it may take several hours to propagate through the DNS network.

Step 4: Prepare your site for deployment to Netlify by creating a “netlify.toml” file

While you’re waiting for the nameserver changes you made in Step 3 to propagate, you can prepare your site for deployment to Netlify from your GitHub, GitLab or Bitbucket account.

When you deploy a Hugo site to Netlify, you can choose how you want it built. You can choose whether you want:

  • your site minified or unminified
  • expired content published or not
  • future-dated posts published or not

… and many other options.

There are two ways to convey this to Netlify:

  1. Specify your Hugo build requirements in the Netlify UI
  2. Specify your Hugo build requirements in a file named netlify.toml which lives in your Hugo repo and is thus version controlled as well as being easier to eyeball.

As you may have inferred from the way I phrased the two choices, I prefer and recommend the second option.

If you want to set your Netlify config up this way too, you’ll need to create a file named netlify.toml in the root of your Hugo site. (It will live at the same level as your config.toml, in other words.)

And here’s the relevant part of my netlify.toml:

[context.production.environment]
	HUGO_VERSION = "0.106.0"
	HUGO_ENV = "production"

[context.deploy-preview.environment]
  HUGO_VERSION = "0.106.0"

[build]
	publish = "public"
	command = "hugo --minify --buildFuture"

As you can see, my build command is "hugo --minify --buildFuture".

This means I have Hugo minify my content, which makes it a bit faster to load, and I also have it build future-dated content.

This is because my timezone in Australia is ahead of Netlify’s in San Francisco, and I don’t want to run into any issues with content not getting published.

If I’m not ready for a post to go live then I do one or more of the following:

  • Commit it to a branch other than main
  • Ensure it has draft: true in its YAML front matter
  • Don’t commit until it’s ready (my repos are all redundantly backed up in iCloud)

Step 5: Deploy your site to Netlify

a) Head to the “Sites” tab

b) Hit “New site from Git”

New site from GitSitesBuildsMembersAudit logTeam settingsDomains

You’ll see the screen below.

c) Choose your Git provider (GitHub, GitLab or Bitbucket)

Create a new siteFrom zero to hero, three easy steps to get your site on Netlify.1. Connect to Git provider2. Pick a repository3. Build options, and deploy!Continuous DeploymentChoose the Git provider where your site’s source code is hosted. When you push to Git, werun your build tool of choice on our servers and deploy the result. GitHub GitLab Bitbucket

d) You’ll then be asked to sign in to your Git provider via a pop up window (not shown here).

I use GitHub so the rest of this tutorial will focus on that. It should be pretty similar for GitLab or Bitbucket, though.

e) You can then choose the repository containing your Hugo site.

Create a new siteFrom zero to hero, three easy steps to get your site on Netlify.1. Connect to Git provider2. Pick a repository3. Build options, and deploy!Continuous Deployment: GitHub AppChoose the repository you want to link to your site on Netlify. When you push to Git, we run your build tool of choice on our servers and deploy the result. moonboothmoonbooth/hugoCan’t see your repo here?Search reposConfigure the Netlify app on GitHub

f) If you don’t see the repo in the list, you’ll need to configure the Netlify app in your Git provider (e.g. GitHub). You can click the green text link named “Configure the Netlify app on GitHub” to do so.

g) Choose your branch (if not master or main).

h) I leave out the Hugo build command and the location of my site (usually /public), as I prefer to specify these in a netlify.toml file which lives at the root of my repo, as specified earlier in this tutorial.

i) Hit “Deploy” and you’re done! Once your DNS changes have propagated, your site will be live on Netlify.

Owner2. Pick a repository3. Build options, and deploy!From zero to hero, three easy steps to get your site on Netlify.Create a new siteDeploy settings for moonbooth/hugoIf you’re using a static site generator or build tool, we’ll need these settings to build your site. Deploy siteLearn more in the docsShow advancedGet more control over how Netlify builds and deploys your site with these settings.1. Connect to a Git providermasterBranch to deployron-erdos’s team

Compression is automatic with Netlify

You don’t need to do anything to enable asset compression with Netlify. In Netlify’s own words:

It just works.

That phrase has become immortal, it seems.

Depending on the asset type (HTML, CSS, JS, SVG etc), Netlify uses either gzip or Brotli compression.

For HTML, CSS and JavaScript, Netlify uses Brotli compression rather than gzip.

Here’s why.

Quoting an Akamai study (which appears to have since been removed), Netlify states:

JavaScript files compressed with Brotli are 14% smaller than gzip.

HTML files are 21% smaller than gzip.

CSS files are 17% smaller than gzip.

That’s good enough for me! Brotli compression is accepted by pretty much all browsers.

For SVG files, Netlify uses gzip compression.

I confirmed this by testing my own site.

When I used Developer Tools to inspect the MoonBooth homepage in Microsoft Edge—using an InPrivate window to avoid the effect of browser extensions—I noticed that:

  1. The HTML document was compressed with Brotli
  2. The CSS stylesheet was also compressed with Brotli
  3. The logo.svg and planets.svg files were compressed with gzip
  4. The favicon.svg was not compressed at all (at 462 bytes, perhaps it would have been made larger by doing so due to the presence of the content-encoding header).

Be aware that browsers recognise Brotli compression, but speed tester Pingdom doesn’t

An interesting fact I discovered recently is that one of the most well-known speed tests—Pingdom—does not recognise Brotli compression and thus marks you down. This is not an issue for SEO—as touched on above, Chrome and Chromium browsers such as Microsoft Edge, Opera and Brave do accept Brotli compression, and in fact, it was developed at Google! If anyone at Pingdom is reading this, I’d encourage you to add Brotli compression to your speed check.

How to 301 redirect your default Netlify subdomain to your primary domain

When you first host a site on Netlify, your site will automatically be published on a Netlify subdomain of the form example.netlify.app.

You can’t eliminate this Netlify subdomain (although you can rename it in the UI). What you can do—and what I recommend you do from an SEO perspective—is 301 redirect it to your primary domain.

The only way to do this is in your /static/_redirects file. When I tried to put this redirect in my /netlify.toml file, it didn’t work. Note: I do keep all my other redirects—for example, if I combine two blog posts—in netlify.toml, and they work just fine.

So, in /static/_redirects, add this:

# Redirect default Netlify subdomain to primary domain
https://example.netlify.app/* https://example.com/:splat 301!

Some points on the above:

  • Obviously you would change example.netlify.app to match your Netlify subdomain; similarly, you would change https://example.com to match your primary domain.
  • The /* and /:splat you see above work together to create a wildcard redirect. So example.netlify.app/my-awesome-blog-post/ will 301 redirect to example.com/my-awesome-blog-post/, and so forth for every piece of content (including the home page).
  • Make sure you use the exclamation mark on the end of the 301, as that is how Netlify forces redirects even when the original file (at example.netlify.app/*) exists.
  • I recommend a 301 redirect, as per the code sample above, unless you have a very good reason to use a 302 redirect.
  • You don’t need to handle the non-https version of the .app Netlify subdomain (or the old .com format if you’re a longstanding Netlify user), as Netlify 301 redirects those to the https version of the .app subdomain automatically.

"Thanks so much for your work ... I'm migrating my WordPress blog to Hugo and it's been really helpful." — Francisco S., engineer and blogger

"I love your content. The information that you provide have been very useful in the development of my personal website." — Mattia C., engineer and researcher

The planets in our solar system