Reading Time & Word Count in Hugo

Posted on | 501 words | ~3 mins

Many Hugo templates include reading time or word count as metadata of blog posts. I think that’s pretty handy, and I always enjoy a little heads up - especially on long blog posts where this info helps me to decide if I read it now or save (read ‘kindle’) it for later.

But what if your favorite template is missing reading time / word count?

It’s pretty simple to add it yourself:

Basics

Start by forking the template on GitHub. When you’re done it’s always nice to create a pull request back to the original author, so I’d recommend checking for a contribution section in the README of your template first.

A simple way to add reading time is to add something along the lines of

{{ if gt .ReadingTime 1 }}
	{{ .Scratch.Set "timeUnit" "mins" }}
{{ else }}
	{{ .Scratch.Set "timeUnit" "min" }}
{{ end }}

~{{.ReadingTime}} {{ .Scratch.Get "timeUnit" }}

wherever you want the reading time to appear.

This snippet will produce 1 min or [x] mins according to the number of minutes.

The reading time is a default feature of Hugo (see variables ).

Similarly, you can add the word count as easily as putting

{{ .WordCount }} words

wherever you want the word count to appear. Again, check the variables help page for more information.

The usual place to put this is /layouts/_default/li.html for the posts list and /layouts/_default/single.html for the post itself. While most templates I’ve seen use these locations, the actual file name could be something else in your case.

Posts and Pages

Many templates use single.html for posts as well as for pages. If you don’t want the reading time to appear on a page, you can surround it with an if-clause like

{{ if eq (.Type | singularize) "post" }}
   [...]
{{ end }}

This will only render its content if your post lies in the posts or post subfolder of content.

Of course, this also works the other way around:

{{ if eq (.Type | singularize) "page" }}
   [...]
{{ end }}

This would only render [...] if the markdown file lies in the pages or page subfolder of content.

Making Things Optional

If you want the option to turn the reading time on or off, you can use a .Param for that.

If you’re using a config.toml, you can add something like

[Params]
hideReadingTime = false

to the [Params] section of it, or if you’re using YAML, add

Params:
    hideReadingTime: false

You can then use another if-clause to hide reading time if the option is set to true.

{{ if not (.Param "hideDate") }}
    [...]
{{ end }}

Conclusion

For a complete example, you can take a look at the single.html and li.html of the theme I used for this site.

I also used partials , to encapsulate reading time and word count .

That’s all! And as you can see at the top of this post - it barely takes 3 minutes to learn how to do it ;)