Complete guide to configuring and managing navigation menus in HBStack framework, including main menus, submenus, and section-based navigation.
This comprehensive guide explains how the HBStack framework handles navigation menus in Hugo. Learn how to configure main menus, create submenus, manage section-based navigation, and customize menu appearance with icons and descriptions. The guide covers both automatic menu generation from content structure and manual menu configuration using YAML files.
The HBStack framework provides a flexible menu system that combines Hugo’s built-in menu functionality with enhanced features for navigation management.
There is a file located in the config/_default/ folder named menus.en.yaml. Since only English is used in this setup, it can be renamed to menus.yaml for simplicity.
Before examining the configuration file, it’s important to understand where the main menus originate:
content directory is considered a section, either as a leaf bundle or branch bundleDocs, Gallery, Examples, and Blog menus_index.md files with explicit menu entriesTip
When menu entries are defined in
_index.mdfiles, there’s no need to use theurlproperty as they are rendered automatically. Only useurlwhen menus are defined in the configuration file. In this case an_index.mdfile can usealiasesto set other URLs. For example/for home page is set in menus.yaml file withhomemenu. But the same destination is set incontent/_index.mdfile withaliases: ["/home/"].1# content/_index.md 2--- 3aliases: 4 - /home/ 5 - /content/ 6---
The Docs menu is generated from its root folder and displays the sidebar with all containing folders when present.
1# content/docs/_index.md
2---
3title: Docs
4menu:
5 main:
6 weight: 1
7 params:
8 icon:
9 vendor: bs
10 name: book
11---
Important Notes:
The Blog menu demonstrates the standard menu configuration pattern:
1# content/blog/_index.md
2---
3title: Blog
4menu:
5 main:
6 identifier: blog
7 weight: 4
8 params:
9 icon:
10 vendor: fas
11 name: blog
12---
Key Properties:
name parameter)blog identifier represents the blog folder and is used for referencingmain parameter is Hugo’s built-in field for the primary navigationNote: The folder name doesn’t matter for menu display. It’s referenced by the
nameparameter if present, otherwise by the title. The identifier is used for internal referencing.
The Blog menu displays five submenus that come from other sections under the content folder: archives, authors, categories, series, and tags. Each has an _index.md file with entries like:
1# content/archives/_index.md
2---
3title: Archives
4menu:
5 main:
6 parent: blog
7 params:
8 icon:
9 vendor: bs
10 name: archive
11 className: text-primary-emphasis
12 description: Posts archive.
13---
Caution
If an index.md file contains a description in front matter, that description will be displayed in the menu. To avoid it happening, add the description under the
paramssection with icon level and it will be displayed in menus followed by the icons.
To make the archives folder appear under blog, the blog identifier is set as the parent property. This pattern applies to all other blog-related folders.
The root content/_index.md file manages the home page menu:
1# content/_index.md
2---
3title: HB Theme Template
4menu:
5 main:
6 name: Home
7 weight: 1
8 params:
9 icon:
10 vendor: bs
11 name: house
12---
13# Note: Content here is not rendered as it's in the root _index.md file
Behavior:
name field overrides the title for display purposesparams/icon with vendor-specific syntaxFor menus that aren’t part of your content sections (like external links), use the menus.yaml file:
1# config/_default/menus.yaml
2main:
3 - name: Support
4 weight: 100
5 url: https://github.com/hbstack
6 params:
7 description: The HB support community.
8 icon:
9 vendor: font-awesome-solid
10 name: headset
Add new menus using the same format:
1main:
2 - name: New Menu
3 identifier: new-menu
4 weight: 200
5 url: https://github.com/example/
6 params:
7 header: Description for the new menu.
8 icon:
9 vendor: font-awesome-solid
10 name: headset
Add submenus using the parent field with the parent’s identifier:
1main:
2 - name: Support
3 identifier: support
4 weight: 100
5 url: https://github.com/hbstack
6 params:
7 header: The HB support community.
8 icon:
9 vendor: font-awesome-solid
10 name: headset
11
12 - name: Documentation
13 parent: support # References the 'support' identifier
14 url: https://hbstack.dev/
15 weight: 1
16 params:
17 icon:
18 vendor: bs
19 name: book
20 className: text-primary
21 description: The documentation.
Important: The
parentfield uses the identifier value, not the display name.
Create content-based submenus by adding a new section folder:
1# content/posts/_index.md
2---
3title: My Posts
4menu:
5 main:
6 parent: blog
7 identifier: posts
8 name: Posts # Display name
9 weight: 1
10 params:
11 icon:
12 vendor: bs
13 name: archive
14 className: text-primary-emphasis
15 description: Personal posts
16---
For nested organization, create subsections:
1# content/posts/hugo/_index.md
2---
3title: Hugo
4menu:
5 main:
6 parent: posts # References the posts identifier
7 weight: 1
8 params:
9 icon:
10 vendor: bs
11 name: archive
12 className: text-primary-emphasis
13 description: About Hugo
14---
Pages within sections don’t need menu entries as they’re managed by their parent bundle:
1---
2date: 2023-10-05T22:40:23+07:00
3title: Hugo Basics
4series:
5 - hugo
6tags:
7 - Static Site Generator
8---
Any page can appear in multiple menus by adding additional menu configurations:
1---
2title: 'Introduction'
3description: |
4 HB (Hugo Bootstrap) is a modular framework built on top of Hugo and Bootstrap v5.3.0+.
5 HB is not a theme, it's used to build themes.
6date: 2022-12-14T19:53:42+08:00
7draft: false
8nav_weight: 1
9series:
10 - Docs
11tags:
12 - Introduction
13authors:
14 - HB
15menu:
16 footer: # Additional menu placement
17 parent: docs
18 weight: 31
19 params:
20 icon:
21 vendor: fas
22 name: hands-clapping
23---
This configuration makes the same page appear in both the main docs section and the footer menu.
_index.md files