Learning to Hugo Part 3: Front Matter



This is the third part of the learning to Hugo series detailing my journey to getting this site up and running! Typical dev appraoch I just installed Hugo and got going. But I have learnt a few things along the way that have improved my development time and hopefully these things will help you. In this section I'm going to explain how to use front matter to manage my content.

Health & safety warning

I'm no web dev! My world is data and so this stuff is outside my area of expertise. I'm learning as I go and so the info I'm sharing is my interpretation of that in a way that makes sense for me as a data-person-doing-web-dev. Some of the technical aspects might be a little misunderstood and I'd love to hear from you in the comments if you think there's a better way or if I've misunderstood a concept. Hopefully outlining my understanding of it might make it easier for someone wanting to give it a go. If you want advanced CSS understanding or web development skills though these are not the posts you're looking for!
obi wan kenobi saying these are not the posts you're looking for

obi wan says these might not be the posts you're looking for

What is front matter

Front matter is essentially metadata embedded in your content file, it provides information that controls how Hugo interacts with your content. All examples below are going to use YAML, but it's possible to write front matter in TOML, YAML or JSON (see Hugo docs on front matter formats).

Front matter can be used to control whether or not a page is listed, or created. It can be used to categorise posts or provide information for other pages for instance creating a list of posts in chronological order.

My front matter

Here is the front matter for this very page at the time of writing;

 2title: "Learning to Hugo Part 3: Front Matter"
 3date: 2021-05-04T09:00:00+01:00
 4image: "/images-shared/thumbs/hugo.png"
 6    - hugo
 8    - getting started
 9    - front matter
10description : How I use front matter to adjust my content
11author: "Justin"

The three hyphens either side of the metadata identify the front matter as being in YAML format. Some of the metadata is theme specific, some is generic;

  • Title is the title that will be displayed in lists on the site.
  • Date represents the created date and will also be presented on the site.
  • Image is theme specific. I've reused this variable for social meta, more on that in a future post.
  • Categories and tags are taxonomy variables and allow you to categorise your posts, it's possible to enter multiple values.
  • Description provides a description of the content, I've not completed this yet. I've reused this variable for social meta, more on that in a future post.
  • Author is currently redundant but I've kept a track on this as I want to put my posts on another site with other authors in future.

Editing this information causes a rebuilt at which point your changes will be reflected on the site. So if I want to change the title of the post, I can simply update the title meta and press save. Let's explore a few more in a bit more detail...

Drafts and scheduling

Creating drafts

The draft variable determines whether a post is built or not. If set to true you can write your post and it will be ignored by Hugo. This is useful if a post is partially complete and you want to save it to continue on another day. Once you are ready to publish you can delete this variable (or set to false) and it will be published.

Here's my post with draft set to true, I can edit the post knowing that it won't be published yet even though the date is 01/05;

2title: "Learning to Hugo Part 3: Front Matter"
3date: 2021-05-01T11:03:45+01:00
4draft: true # draft post, Hugo will ignore

Scheduling posts

The date variable represents the created date of your post and also controls the date on which a post will be published. If you set the date into the future and press save, the post will disappear from your post list. This is because it is not due to be published until the date you've set and so Hugo won't build it. In fact, it won't appear on your published site unless you rebuild your site on the date of scheduling. This is a great way of scheduling posts into the future so long as you have planned a way of rebuilding on the desired date!

Here's my post with a scheduled date into the future. I can push this to my remote repository and it won't get built until 10th May;

2title: "Learning to Hugo Part 3: Front Matter"
3date: 2021-05-10T11:03:45+01:00 # to be published on 2020-05-10 at 11:03

Viewing drafts or scheduled posts

Working with drafts or scheduled posts is great, but what if you're previewing your site locally and want to view the scheduled post? This is where a few switches come in. Stop your site and then run one of the three commands below;

1hugo server -D # show all drafts (but no future scheduled posts)
2hugo server -F # show all future scheduled posts
3hugo server -D -F # show all drafts AND future scheduled posts


So when I moved from Wordpress to Hugo I changed my URL structure. I didn't quite think this through at the time, but that essentially had the effect of breaking any links to my old posts. Now my blog isn't very mature, even less so at the time, but I had a few posts that had been promoted by Redgate and these links broke when I moved. Rather than tyring to resurrect the old URL you can apply aliases to posts which essentially work as a redirect to the correct post.

My Redgate post was located at a different URL on my old site;

  • [old site]/2019/03/13/compliant-database-development-using-redgate-sql-provision
  • [new site]/2019/redgate-sql-provision-first-look-part1

The curse of tinkering! I guess for most people with mature blogs they would look to mirror the URL structure which makes a lot of sense (doh!), but because I only had a few posts to preserve, I simply made use of the alias variable. So my redgate post has the following config;

 2title: "SQL Provision First Look Part1"
 3date: 2019-10-01T09:00:00+00:00
 4watermark: "Blog"
 5image: "thumb.png"
 7    - redgate
 9    - sqlclone
10    - datamasker
11    - compliance
12description : First look at Redgate SQL Provision
13author: Justin
15    - /2019/03/13/compliant-database-development-using-redgate-sql-provision/

So the post is created at following path because of the file structure;


But if anyone clicks on a link from Redgate it will look for;


But it will then be redirected to the new location!

You can also create multiple aliases for posts. I've not explored this but I've read ideas where you might want to improve SEO for posts by including different words.


Type can be used to manage the layout for a specific post. When a post is created, Hugo will determine a content type based on the name of the root section unless overridden by the type variable in a page's front matter. Supposing you have a post in a folder called blog, the page type will be blog and Hugo will use content lookup to determine the layout of each post. So Hugo will look for blog.html and the layout defined within that file will be applied.

But supposing you have one post that doesn't quite work for that layout. You could create a copy of the blog.html layout file, give it a distinct name, adjust the layout as required and then set your post to that type by adding a type variable to your front matter.


So for this example, I want to create a layout that doesn't include the navigation block. All of my posts have previous and next buttons to navigate through my posts. For this one, I'm going to adjust the layout so they don't exist. I need to create a new layout file and I need to override the content type.

Create layout

I'm going to create a new type called "no-nav". I haven't created any custom layouts so far, so I know that all of my posts seek out this default file within my theme;


I can copy that file and place it inside of my layouts folder and make adjustments. Based on the Hugo documentation, Hugo looks for a subfolder in the layouts folder that is named the same as the type therefore, I'll copy my single.html file and place it at the following path;


So that has now created a content type called no-nav. Next, I'll open the file and comment out the code block that renders the nav block. I'm not going to show examples here because I'm assuming this is going to be inherently different for most themes. Once I'm happy with my new layout, I can save the file and close it.

All that is left is telling Hugo which files I wish to pick up the new layout. So for this very post, I've added the type variable to the front matter and set the value to "no-nav";

 2title: "Learning to Hugo Part 3: Front Matter"
 3date: 2021-05-04T09:00:00+01:00
 4image: "/images-shared/thumbs/hugo.png"
 6    - hugo
 8    - getting started
 9    - front matter
10description : How I use front matter to adjust my content
11author: "Justin"
12type: no-nav

And when I hit save, the navigation block in this post disappears. I'll preserve the layout for this post - if you switch between this post and another one you'll notice that all other posts have a consistent layout whereas this post doesn't have the navigation block. Pretty neat! Now in reality, this isn't a practical change, but you might want to exclude a preview image, or drastically adjust the layout for a certain type of post.

More reading

Any comments?

I'd love to hear from you in the comments. If you think something needs more explanation or I've not quite understood a concept, if you have a question or just want to say hi please drop me a message in the comments!


If you made it all the way down here, thanks for reading my post and enjoy your day.