Navigation and Menus

Customize site navigation for your Docsy site.

Docsy provides multiple built-in navigation features for your sites, including site menus, side navs, and page table of contents (TOC). This page shows you how they work and how to configure and customize them to meet your needs.

A site navbar appears at the top of every site page. It is built from Hugo menus and Docsy-generated elements. Hugo menus consist of an array of menu entries, accessible via the .Site.Menus site variable.

The main menu is build from:

Adding main menu entries

Define menu entries in your site’s configuration file or via page front matter. For example, here’s how you can add a Documentation section to the top-level navbar:

title = "Welcome to Docsy"
linkTitle = "Documentation"

[menu.main]
weight = 20
pre = "<i class='fa-solid fa-book'></i>"
title: Documentation
linkTitle: Docs
menu:
  main:
    weight: 20
    pre: <i class='fa-solid fa-book'></i>
{
  "title": "Documentation",
  "linkTitle": "Docs",
  "menu": {
    "main": {
      "weight": 20,
      "pre": "<i class='fa-solid fa-book'></i>"
    }
  }
}

Navbar entries are ordered from left to right by weight. So, for example, a section index or page with weight: 30 would appear after the Documentation section in the menu, while one with weight: 10 would appear before it.

If you want to add a link to an external site to this menu, add it to your site configuration:[^add-external-link-via]

[[menu.main]]
  name = "Example Site"
  weight = 40
  url = "https://example.docsy.dev"
  post = "<sup><i class='fa-solid fa-up-right-from-square fa-xs' aria-hidden='true'></i></sup>"
menu:
  main:
    - name: Example Site
      weight: 40
      url: https://example.docsy.dev
      post:
        <sup><i class="ps-1 fa-solid fa-up-right-from-square fa-xs"
        aria-hidden="true"></i></sup>
{
  "menu": {
    "main": [
      {
        "name": "Example Site",
        "weight": 40,
        "url": "https://example.docsy.dev",
        "post": "<sup><i class='fa-solid fa-up-right-from-square fa-xs' aria-hidden='true'></i></sup>"
      }
    ]
  }
}

Version menu

Docsy adds a version selector menu to the top-level navbar if you have doc versions configured as explained in Doc versioning.

To style the version menu, apply your custom CSS to .td-navbar__version-menu.

Language menu

Docsy adds a language selector menu to the top-level navbar if you have a multilingual site configured as explained in [Multi-language support][]. Selecting a language takes the user to the translated version of the current page, or the home page for the given language.

The menu is visible in the navbar for all screen sizes. By default, the current site language name is shown. On narrow displays, this is replaced by the language code.

To style the language menu, apply your custom CSS to .td-navbar__lang-menu.

Light/dark theme menu

Docsy adds a light/dark theme selector menu to the top-level navbar if you have it configured as explained in Light/dark mode menu.

To style the light/dark mode menu, apply your custom CSS to .td-navbar__light-dark-menu.

To configure site search, see Search. When configured, the search box appears as the last item in the top-level navbar, as well as the sidebar on mobile.

To style the search menu, apply your custom CSS to .td-navbar__search.

Adding icons to the navbar

As described in the Hugo docs, you can add icons to the navbar by using the pre and/or post parameter for main menu items defined in your site’s hugo.toml/hugo.yaml/hugo.json or via page front matter. For example, the following configuration adds the GitHub icon to the GitHub menu item, and a New! alert to indicate that this is a new addition to the menu.

[[menu.main]]
  name = "GitHub"
  weight = 50
  url = "https://github.com/google/docsy/"
  pre = "<i class='fa-brands fa-github'></i>"
  post = "<span class='alert'>New!</span>"
menu:
  main:
    - name: GitHub
      weight: 50
      url: 'https://github.com/google/docsy/'
      pre: <i class='fa-brands fa-github'></i>
      post: <span class='alert'>New!</span>
{
  "menu": {
    "main": [
      {
        "name": "GitHub",
        "weight": 50,
        "url": "https://github.com/google/docsy/",
        "pre": "<i class='fa-brands fa-github'></i>",
        "post": "<span class='alert'>New!</span>"
      }
    ]
  }
}

You can find a complete list of icons to use in the FontAwesome documentation. Docsy includes the free FontAwesome icons by default.

Side navigation

A side nav1 for section navigation is shown in the left panel of the docs and blog pages. It is automatically built from the content tree. Like the navbar, it is ordered by page or section index weight (or by page creation date if weight is not set), with the page or index’s Title, or linkTitle if different, as its link title in the menu. If a section subfolder has pages other than _index.md or _index.html, those pages will appear as a submenu, again ordered by weight. For example, here’s the metadata for this page showing its weight and title:

title = "Navigation and Search"
linkTitle = "Navigation and Search"
date = 2017-01-05T00:00:00.000Z
weight = 3
description = '''
Customize site navigation and search for your Docsy site.
'''
title: 'Navigation and Search'
linkTitle: 'Navigation and Search'
date: 2017-01-05
weight: 3
description: >
  Customize site navigation and search for your Docsy site.
{
  "title": "Navigation and Search",
  "linkTitle": "Navigation and Search",
  "date": "2017-01-05T00:00:00.000Z",
  "weight": 3,
  "description": "Customize site navigation and search for your Docsy site.\n"
}

To hide a page or section from the left navigation menu, set toc_hide: true in the front matter.

To hide a page from the section summary on a docs section landing page, set hide_summary: true in the front matter. If you want to hide a page from both the TOC menu and the section summary list, you need to set both toc_hide and hide_summary to true in the front matter.

title = "My Hidden Page"
weight = 99
toc_hide = true
hide_summary = true
description = '''
Page hidden from both the TOC menu and the section summary list.
'''
title: 'My Hidden Page'
weight: 99
toc_hide: true
hide_summary: true
description: >
  Page hidden from both the TOC menu and the section summary list.
{
  "title": "My Hidden Page",
  "weight": 99,
  "toc_hide": true,
  "hide_summary": true,
  "description": "Page hidden from both the TOC menu and the section summary list.\n"
}

Side-nav options

By default, the side nav shows the current section fully expanded all the way down. This may make the left nav too long and difficult to scan for bigger sites. Try setting site parameter ui.sidebar_menu_compact = true in hugo.toml.

With the compact menu (.ui.sidebar_menu_compact = true), only the current page’s ancestors, siblings and direct descendants are shown. You can use the optional parameter .ui.ul_show to set a desired menu depth to always be visible. For example, with .ui.ul_show = 1 the first menu level is always displayed.

The number of sidebar entries shown per section can be configured using the .ui.sidebar_menu_truncate parameter (default: 100).

As well as the completely expanded and compact menu options, you can also create a foldable menu by setting the site parameter ui.sidebar_menu_foldable = true in hugo.toml. The foldable menu lets users expand and collapse menu sections by toggling arrow icons beside the section parents in the menu.

On large sites (default: > 2000 pages) the side nav is not generated for each page, but cached for the whole section. The HTML classes for marking the active menu item (and menu path) are then set using JS. You can adjust the limit for activating the cached side nav with the optional parameter .ui.sidebar_cache_limit.

The tabbed pane below lists the menu section options you can define in your project configuration file.

[params.ui]
sidebar_menu_compact = true
ul_show = 1
sidebar_menu_foldable = true
sidebar_cache_limit = 1000
params:
  ui:
    sidebar_menu_compact: true
    ul_show: 1
    sidebar_menu_foldable: true
    sidebar_cache_limit: 1000
{
  "params": {
    "ui": {
      "sidebar_menu_compact": true,
      "ul_show": 1,
      "sidebar_menu_foldable": true,
      "sidebar_cache_limit": 1000
    }
  }
}

Adding icons to the side nav

You can add icons to the side nav in the sidebar by setting the icon parameter in the page front matter (e.g. icon: fa-solid fa-screwdriver-wrench).

You can find a complete list of icons to use in the FontAwesome documentation. Docsy includes the free FontAwesome icons by default.

Out of the box, if you want to use icons, you should define icons for all items on the same menu level in order to ensure an appropriate look. If the icons are used in a different way, individual CSS adjustments are likely necessary.

By default the side nav is entirely generated from your section’s pages. If you want to add a manual link to this menu, such as a link to an external site or a page in a different section of your site, you can do this by creating a placeholder page file in the doc hierarchy with the appropriate weight and some special parameters in its metadata (frontmatter) to specify the link details.

To create a placeholder page, create a page file as usual in the directory where you want the link to show up in the menu, and add a manualLink parameter to its metadata. If a page has manualLink in its metadata, Docsy generates a link for it in the side nav for this page and in the section index (the list of the child pages of a section on a landing page - see description in the Docsy docs), but the link destination is replaced by the value of manualLink. The link text is the title (or linkTitle if set) of your placeholder page. You can optionally also set the title attribute of the link with the parameter manualLinkTitle and a link target with manualLinkTarget - for example if you want an external link to open in a new tab you can set the link target to _blank. Docsy automatically adds rel=noopener to links that open new tabs as a security best practice.

You can also use manualLink to add an additional cross reference to another existing page of your site. For internal links you can choose to use the parameter manualLinkRelref instead of manualLink to use the built-in Hugo function relref. If relref can’t find a unique page in your site, Hugo throws a error message.

To help readers stay focused within a section, you can “root” a section in the sidebar navigation. This is particularly useful when there is deeply nested pages.

Enable the feature in your site configuration:

params:
  ui:
    sidebar_root_enabled: true

Then add sidebar_root_for to a section’s _index.md. Available options are:

  • self applies the rooted sidebar to the index page as well as descendants.
  • children keeps the section’s index page in the global docs menu, but limits descendant pages to the rooted sidebar.

Example:

---
title: API Reference v2.0
linkTitle: v2.0
sidebar_root_for: self
---

Examples:

sidebar_root_forExample
selfContent and customization
childrenBest practices

To navigate out of a rooted section, click the “up” icon in the sidebar next to the section title.

Feature notes:

  • You can nest rooted sections.
  • Docsy will warn you if you set sidebar_root_for to self on a section root page, since it is redundant.
  • Docsy will generally ignore sidebar_root_for for non “docs” pages and non-section index pages.

Table of contents

Docsy provides a table of contents (TOC) for each “docs"page. The TOC is generated from the headings in the page content. The TOC is displayed in the right-hand sidebar by default.

Active TOC entry tracking with ScrollSpy

Docsy highlights the active heading in the TOC sidebar using Bootstrap ScrollSpy. By default, headings become active when they reach 10% from the top of the viewport (configured via rootMargin).

  • To disable ScrollSpy for a specific page, set ui.scrollSpy.disable: true in that page’s front matter. To disable for all pages in a section, cascade the setting in the front matter of the section’s index page.

  • To globally adjust when headings become active, set ui.scrollSpy.rootMargin in your site configuration. The default is 0px 0px -10%. Use a larger negative percentage (e.g., -20%) to activate headings earlier, or a smaller one (e.g., -5%) to activate them later.

    [params.ui.scrollSpy]
    rootMargin = "0px 0px -15%"
    
    params:
      ui:
        scrollSpy:
          rootMargin: 0px 0px -15%
    
    {
      "params": {
        "ui": {
          "scrollSpy": {
            "rootMargin": "0px 0px -15%"
          }
        }
      }
    }
    

Advanced ScrollSpy customization

For advanced customization, such as adjusting threshold, override layouts/_partials/td/scrollspy-attr.txt. For ScrollSpy configuration details, see ScrollSpy.

Breadcrumb navigation appears at the top of each non-index page be default. To also display single-element breadcrumb lists in index pages, add the following style override to your project:

.td-breadcrumbs__single {
  display: inline !important;
}

Breadcrumb navigation is also shown for each item in the taxonomy results page — that is, when you click one of the taxonomy labels such as Categories or Tags.

As illustrated next, you can disable (non-taxonomy) breadcrumb navigation for an entire project, by setting ui.breadcrumb_disable to true in your project configuration file. Similarly, you can disabled taxonomy breadcrumbs by setting ui.taxonomy_breadcrumb_disable to true:

[params.ui]
breadcrumb_disable = true
taxonomy_breadcrumb_disable = true
params:
  ui:
    breadcrumb_disable: true
    taxonomy_breadcrumb_disable: true
{
  "params": {
    "ui": {
      "breadcrumb_disable": true,
      "taxonomy_breadcrumb_disable": true
    }
  }
}

To disable breadcrumbs in a specific page or section set ui.breadcrumb_disable to true in the page or section-index front matter. Here is an example of the latter:

cascade:
  params:
    ui:
      breadcrumb_disable: true

Docsy supports build-time generation of heading self links using Hugo’s render-heading.html hook.

To enable this feature in your project, define layouts/_markup/render-heading.html as:

{{ partial "td/render-heading.html" . }}

The heading self-link anchor class is .td-heading-self-link, which you can customize for your project. By default, the heading self-link style has these defaults:

  • The self-link symbol is #.
  • The symbol is always visible on mobile and touch devices, otherwise it is only visible on hover or focus.

Your projects can also reuse (in your own custom heading render hook) or override the heading self-link partial td/heading-self-link.html, which is defined in layouts/_partials/td/render-heading.html.


  1. Formerly named the “section menu”. ↩︎