Navigation and Menus
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.
Site navbar
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:
- Menu entries defined over the
mainmenu. - Docsy-generated menus (depending on your site configuration):
- Docsy-generated search box
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.
Prior to Docsy 0.13.0, the language selector menu could also be visible from the left sidebar, and its visibility in the navbar depended on the screen size. For details, including ways to restore the legacy behavior, see Language menu visibility.
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.
Search box
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.
Adding manual links to the side nav
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.
Although all generated menu and landing page links
based on your placeholder file are set according to the parameters manualLink
or manualLinkRelref, Hugo still generates a regular HTML site page for the
file, albeit one with no generated links to it. To avoid confusion if users
accidentally land on a generated placeholder page, we recommend specifying the
URL for the external link in the normal content and / or page description of the
page.
Section as sidebar root (EXPERIMENTAL)
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:
selfapplies the rooted sidebar to the index page as well as descendants.childrenkeeps 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_for | Example |
|---|---|
self | Content and customization |
children | Best 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_fortoselfon a section root page, since it is redundant. - Docsy will generally ignore
sidebar_root_forfor 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.
The headings contained in Markdown shortcodes {{% ... %}} get included
in the TOC, while those in standard shortcodes {{< ... >}} will not. For
details, see Hugo forum discussions #55399 and #51940.
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: truein 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.rootMarginin your site configuration. The default is0px 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%" } } } }Smooth scrolling issueWe previously enabled ScrollSpy’s smooth scrolling, but it interfered with hash updates in the browser URL and in-page navigation, so it is disabled by default. For details see PR #2291.
Advanced ScrollSpy customization
For advanced customization, such as adjusting threshold, override
layouts/_partials/td/scrollspy-attr.txt. For ScrollSpy configuration details,
see ScrollSpy.
ScrollSpy determines the active TOC entry using the browser’s IntersectionObserver API, including its configurable rootMargin. Because of how these thresholds work, there can be brief moments while a user is scrolling when no heading is highlighted, especially when headings are close together or when the active region is small. For more details, see ScrollSpy options and the discussion in Bootstrap issue #34958.
Breadcrumb navigation
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
Heading self links
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.
Formerly named the “section menu”. ↩︎
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.