This article may contain affiliate links. If you buy some products using those links, I may receive monetary benefits. See affiliate disclosure here
When using content management system like WordPress, adding table of contents to your posts is quite straightforward – just install a plugin, and that’s it.
However, when using a static site generator like Hugo, that too when you use markdown to write content, it may not be that obvious.
So in this quick post, we will discuss how to set up table of contents in your Hugo blog.
We’ll be discussing two methods below:
- add table of contents within posts content using shortcodes
- add it in the template
The toc shown above is generated with the first method
Watch Video
In the first method that uses shortcode, you will have to call the shortcode tag manually in each markdown file. The advantage is, you can place it anywhere in the post – before the first heading, after the first paragraph, etc.
In the second method, we will add the table of contents in our single.html
template file. So the table content will be added automatically to all our post pages when Hugo renders the HTML. However, the downside is, you can only add it at the beginning or end of a post.
Before that, you should know about two things:
- Hugo’s .TableOfContents variable, and
- autoHeadingIDs in Goldmark renderer
The .TableOfContents
Variable
Hugo offers a built-in page variable called .TableOfContents, which contains the markup for table of contents.
So you don’t need to parse anything manually. Just like you pull front matter data using Hugo page variables, you can call this variable inside your templates.
Ensuring autoHeadingID
is enabled
In addition to the .TableOfContents variable, this is another handy feature that Hugo offers by default.
If you are not aware, Hugo makes use of the Goldmark markdown parser to convert your content files to HTML. And during that process, it also generates unique ID attributes for all headings based on its text.
Although the autoHeadingID is enabled by default, some themes or configurations may disable it from the site’s config file. If it is explicitly disabled, the anchor links in the table of contents won’t work.
So, ensure that your theme or site’s config file does not set the autoHeadingID value to false.
Method 1: Adding Table Of Contents in Markdown
Create a Shortcode
Create a file called toc.html
with the below HTML markup, and place it inside the layouts/shortcodes
directory in your site’s root. If you are using a theme, you can place it there also.
<div>
<h2>Table Of Contents</h2>
{{ .Page.TableOfContents }}
</div>
By the way, the name of the file doesn’t matter, although here we named it as toc.html
.
Also, note that we have to add .Page variable in front of the .TableOfContents variable, since we are calling it inside a shortcode. If it were in a template file, we could directly call it without prefixing .Page.
Call the Shortcode inside Markdown
Now you can call the above shortcode from any markdown file in your content directory:
{{</* toc */>}}
Note that the name of the shortcode is the same as its file name without the .html part.
Method 2: Adding TOC in Template
Adding table of contents in the template is even more simple. You can just call the .TableOfContents variable directly inside your single.html
file like this:
Configurations
The built-in variable supports three configuration variables:
tableOfContents:
endLevel: 3
ordered: false
startLevel: 2
The endLevel
and startLevel
specifies the heading levels that you want to include in the TOC. With the above code, it includes h2
and h3
tags.
Instead, if you want to limit it to h2
tags only, set both the endLevel
and startLevel
values to 2.
With the ordered
value set to false, which is the default value, your table of contents will show up in an HTML unordered list <ul>
. Instead if you set it to true
, it will be rendered inside an ordered list <ol>
.