Freedom

Table of Contents

·   1 min ·   Gautham Chettiar

Displays a table of contents generated from page headings with optional sticky behavior.

Location : layouts/_partials/widgets/meta/toc.html

Parameters :

ParameterTypeDescriptionDefault
pagePagePage contextrequired
siteSiteSite contextrequired
titlestringTOC heading title"Table of Contents"
classstringAdditional CSS classes-
keystringConfig key for visibility"Toc"
stickyboolEnable sticky TOC behaviorfrom config

Configuration :

yaml
params:
  # Basic TOC settings
  showToc: true  # Show/hide table of contents
  
  # Sticky TOC settings
  stickyToc: true              # Enable sticky TOC on scroll
  stickyTocPosition: "right"   # Position: "left" or "right"
  stickyTocMinWidth: 1280      # Minimum viewport width for sticky (px)

# Page-level override
---
title: "My Page"
params:
  stickyToc: false  # Disable sticky for this page
---

# TOC generation settings (in hugo.yaml markup config)
markup:
  tableOfContents:
    startLevel: 2    # Start at h2
    endLevel: 4      # End at h4
    ordered: false   # Use ul, not ol

Sticky TOC Behavior :

The sticky table of contents appears on the side of your content when:

  1. The user scrolls past the main TOC
  2. The viewport is wide enough (default: 1280px minimum)
  3. There’s enough space beside the content area

Features:

Examples :

go
// Basic usage
{{ partial "widgets/meta/toc.html" (dict "page" . "site" .Site) }}

// With custom title
{{ partial "widgets/meta/toc.html" (dict 
  "page" . 
  "site" .Site 
  "title" "On This Page"
) }}

// Disable sticky for specific page
{{ partial "widgets/meta/toc.html" (dict 
  "page" . 
  "site" .Site 
  "sticky" false
) }}

// With custom class
{{ partial "widgets/meta/toc.html" (dict 
  "page" . 
  "site" .Site 
  "class" "sidebar-toc"
) }}

Styling :

The TOC widget uses these CSS classes:

Customize via CSS custom properties:

css
.toc-sticky {
  --spacing-md: 1.5rem;  /* Adjust padding */
  max-width: 320px;      /* Wider sticky TOC */
}