How to create multilevel dropdown menu in hugo?

You need to do three things to generate multilevel dropdown menu in Hugo:

1. Add menu and submenu configuration in config.toml file

...
[menu]
  [[menu.main]]
    identifier = "category"
    name = "Category"
    url = "/category"
    weight = 1
  [[menu.main]]
    identifier = "category1"
    name = "Category1"
    url = "/category/1"
    parent = "category"
    weight = 1
  [[menu.main]]
    identifier = "category2"
    name = "Category2"
    url = "/category/2"
    parent = "category"
    weight = 2
  [[menu.main]]
    identifier = "category3"
    name = "Category3"
    url = "/category/3"
    parent = "category"
    weight = 3

You should understand each field under [[menu.main]]:

  • identifier should be unique name of menu within the menu structure. It is used to identify menu, submenu and their relation by hugo internally.
  • name should be the name which you want to display on the menu item.
  • url is a relative URL which will be opened when you click on the menu item.
  • weight is for sequencing the menu items. Menu items with less weight appear first in the menu. Same is applicable for submenu, submenu items with less weight appear first in the dropdown.
  • parent is used in submenu item only to tell who is the parent of the submenu. You use the identifier of the parent menu in this field.

2. Create a partial menu.html to generate HTML from the configuration

{{ range .Site.Menus.main }}
    {{ if .HasChildren }}
        <li class="{{ if $currentPage.HasMenuCurrent "main" . }}active{{ end }}">
                <span>{{ .Name }}</span>
            <ul class="sub-menu">
            {{ range .Children }}
            ...
        </li>
     ...

Things to note in the above partial is use of {{- if .HasChildren }} condition to check if menu has submenu children or not. If it is having submenu children, then we loop them through using {{ range .Children }}

3. Apply CSS for menu and submenu

This is the most important part to apply responsive CSS so that it works for both desktop and mobile.

I used Hugo to generate my blog website and added support for the nested menu structure. I have written an article for all the changes I have done on my Hugo website to support the nested menu.