Lesson Overview

Single Pages

Learn about Single Page templates for displaying a single post.
4 minutes 767 words

Before we start writing awesome blog posts, we need to create a layout for displaying them.

Right now when we click a link on our homepage, we see a 404 error. Let’s fix that.


Create a file called single.html inside the layouts/_default folder.

Your project structure should look like this:

β”œβ”€β”€ archetypes
|   └── default.md
β”œβ”€β”€ content
|   └── posts
|       └── my-first-post.md
β”œβ”€β”€ data
β”œβ”€β”€ layouts
|   β”œβ”€β”€ _default
|   |   β”œβ”€β”€ summary.html
|   |   β”œβ”€β”€ single.html
|   |   └── baseof.html
|   └── index.html
β”œβ”€β”€ static
β”œβ”€β”€ themes
└── config.toml

Open the new single.html file and paste the following:

{{ define "main" }}
  <h1>{{ .Title }}</h1>
      {{ .Content }}
      <h4>{{ .Date.Format "Mon Jan 2, 2006" }}</h4>
      <h5>{{ .WordCount }} Words</h5>
    {{ with .PrevInSection }}
    <a class="previous" href="{{ .Permalink }}"> {{.Title}}</a>
    {{ end }}
    {{ with .NextInSection }}
    <a class="next" href="{{ .Permalink }}"> {{.Title}}</a>
    {{ end }}
{{ end }}

Before explaining the details of the above snippet. Go ahead and save that and visit your site running on localhost. If you click the link on the homepage now, you should be directed to a real page with details about the post.

We can see now that this single.html layout is made for displaying one post at a time. No matter what kind of content is in a post, this is the layout that Hugo will use for displaying it.

If you edit the my-first-post.md file and add some more text to it, you will see the server update and show the new content.


In the single.html layout, we display the title of our post using the {{ .Title }} variable that Hugo injects for us. This is taken directly front the markdown front matter, this is the weird metadata at the top of the markdown file.


We also display the content of the post. The content is everything in the markdown file below the front matter section.

We access this data through the content variable that Hugo gives us, like this: {{ .Content }} and it will convert our markdown to HTML automatically. This is why content authors use Markdown instead of HTML to write blog posts, because Markdown is faster to write and it’s easy for computers to convert it to more complex HTML code for display in browsers.


We also display the date of the post in our single page layout. Hugo takes it from the front matter of our markdown file and allows us to format it in any way that we like using the .Date.Format function.

If you had a blog post with a date of 2017-03-03T14:15:59-06:00, then the table below shows what it would be formatted to in column 2 if you used the format in column 1.

“Monday, January 2, 2006”Friday, March 3, 2017
“Mon Jan 2 2006”Fri Mar 3 2017
“January 2006”March 2017

Note that the values in column 1 should not be changed. The Monday, January, 2, and 2006 are special values and are used just for formatting. In the real HTML generated, they will be replaced with the correct date from your post front matter.

For more detail about formatting dates, visit the Hugo date format documentation page.

Hugo has dozens of functions available to be used inside templates, but we will only cover a few basic ones in this course.

Word Count

Hugo also injects information into our template like, the word count of our post, the reading time it would take to read the post and many others.

To access word count, we would write this inside a single page template: {{ .WordCount }}.

We can see all page variables available to us in the full Hugo documentation for page variables.

Next & Previous Sections

Hugo also gives you access to knowing which post is next in the folder. This allows us to create links at the bottom of our posts to the next and previous posts. Hugo sorts our posts by date automatically so we don’t have to worry about it. But if we wanted a specific order, we can add a weight field to our posts front matter and Hugo will sort by that value instead. The lower the number for the weight, the higher it will rank.

To create next and previous links, we use the {{ with }} syntax, which automatically check if a variable exists before displaying the code inside, then provides the context of the variable through {{ . }} syntax.

Share this page