Left Nav Pane
About
This page tests the addition of a left navigation pane in pages created in the writing category, though I just created a page in the about category and it too displays the left nave pane.
Left Nav Pane
Here is the Markdown content returned in response to a prompt to add this feature.
Steps to display a left navigation pane listing H1 headings on /writing/ pages.
1. hugo.toml — Include H1 in table of contents
Add to the bottom of the file:
[markup.tableOfContents]
startLevel = 1
endLevel = 1
2. layouts/_default/single.html — Add TOC sidebar
Wrap the article in a layout container and render .TableOfContents:
{{ define "main" }}
<div class="prose-layout">
{{ if .TableOfContents }}
<nav class="prose-toc" aria-label="On this page">
<span class="prose-toc-label">On this page</span>
{{ .TableOfContents }}
</nav>
{{ end }}
<article class="prose">
<header class="prose-header">
{{ with .Date }}
<time class="prose-date" datetime="{{ .Format "2006-01-02" }}">
{{ .Format "2006-01-02" }}
</time>
{{ end }}
<h1 class="prose-title">{{ .Title }}</h1>
{{ with .Description }}
<p class="prose-desc">{{ . }}</p>
{{ end }}
{{ with .Params.tags }}
<div class="prose-tags">
{{ range . }}<span class="tag">{{ . }}</span>{{ end }}
</div>
{{ end }}
</header>
<div class="prose-body">
{{ .Content }}
</div>
</article>
</div>
{{ end }}
3. assets/css/main.css — Style the layout
Add these rules to the CSS file:
.prose-layout {
display: flex;
gap: 48px;
align-items: flex-start;
}
.prose-toc {
position: sticky;
top: 32px;
min-width: 180px;
flex-shrink: 0;
}
.prose-toc-label {
display: block;
font-family: var(--mono);
font-size: 10px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--faint);
margin-bottom: 10px;
}
.prose-toc ul { list-style: none; }
.prose-toc a {
font-family: var(--mono);
font-size: 11px;
color: var(--muted);
text-decoration: none;
line-height: 1.8;
}
.prose-toc a:hover { color: var(--signal); }
Notes
- Hugo generates
.TableOfContentsautomatically from headings in the markdown content. - The
startLevel/endLevelconfig controls which heading levels are included. Setting both to1means only H1s appear in the nav. - The
{{ if .TableOfContents }}guard means the nav only renders on pages that have headings — pages without H1s won’t show an empty sidebar. - The
position: stickyon.prose-tockeeps the nav visible as the user scrolls.
Next Steps
I dislike the font size that the left nav pane menu uses.
TODO:
- Increase font size