# How to create a multi-level menu in Bubble.io: Step-by-Step Guide

- Tool: Bubble
- Difficulty: Beginner
- Time required: 15-20 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## TL;DR

Create a multi-level navigation menu in Bubble using a hierarchical data structure with parent-child category relationships. Build the menu with nested Repeating Groups inside hover-triggered groups, showing submenus when users hover over parent items. For mobile, implement a hamburger menu with collapsible sections using custom states to toggle visibility.

## Building a Multi-Level Navigation Menu in Bubble

Multi-level navigation menus help users browse complex category structures — think of e-commerce sites with departments, subcategories, and sub-subcategories. This tutorial shows you how to build a dynamic, database-driven menu in Bubble that supports hover-to-reveal submenus on desktop and collapsible sections on mobile, all managed through your Data tab without any code.

## Before you start

- A Bubble account with an app open in the editor
- Basic understanding of Repeating Groups and conditional visibility
- Familiarity with custom states in Bubble

## Step-by-step guide

### 1. Create the Category Data Type with parent-child relationships

Go to Data tab → Data types and create a 'Category' Data Type with fields: name (text), slug (text), parent_category (Category — this creates the self-referencing hierarchy), sort_order (number), page_link (text, the page URL to navigate to), and icon (image, optional). Top-level categories will have an empty parent_category field. Second-level categories will reference a top-level category as their parent. This structure supports unlimited nesting levels.

> Pro tip: Use the sort_order number field to control the display order of menu items. This lets you rearrange the menu without editing any design elements — just change the numbers in the database.

**Expected result:** A Category Data Type exists with self-referencing parent_category field enabling hierarchical relationships.

### 2. Add sample menu categories to the database

Go to Data tab → App data → Category. Click 'New entry' and create your top-level categories first (with parent_category left empty): Products (sort_order: 1), Services (sort_order: 2), Resources (sort_order: 3). Then create subcategories with their parent set: under Products, add 'Software' (parent: Products, sort_order: 1), 'Hardware' (parent: Products, sort_order: 2). Under Software, add 'Desktop Apps' (parent: Software, sort_order: 1), 'Mobile Apps' (parent: Software, sort_order: 2).

**Expected result:** Your database contains a hierarchical set of categories with parent-child relationships and sort ordering.

### 3. Build the top-level horizontal menu bar

On your page (or in a reusable NavBar element), add a Repeating Group set to layout type 'Row' (horizontal). Set Type of content to 'Category' and Data source to 'Do a search for Categories' with constraint: parent_category is empty, sorted by sort_order ascending. This shows only top-level items. Inside each cell, add a Text element displaying 'Current cell's Category's name.' Style the Repeating Group as a horizontal bar with appropriate spacing and colors.

**Expected result:** A horizontal menu bar displays all top-level categories in the correct order.

### 4. Add hover-triggered dropdown submenus

Inside each cell of the top-level Repeating Group, add a Group below the category name text. Set this group to not be visible on page load. Add a conditional: 'When This Group is hovered → This element is visible.' Inside this dropdown group, add another Repeating Group (vertical this time) with Type of content 'Category' and Data source: 'Do a search for Categories' where parent_category = Parent group's Category. This shows all children of the hovered item. Style the dropdown with a white background, shadow, and absolute positioning so it overlays the page content.

> Pro tip: Set the dropdown group's position to 'Align to Parent' with top-left alignment so it appears directly below its parent menu item. Add a slight delay using 'Do when condition is true' with a custom state to prevent the menu from flickering on quick mouse movements.

**Expected result:** Hovering over a top-level menu item reveals a dropdown showing its subcategories.

### 5. Add a third level for sub-subcategories

Inside each cell of the subcategory Repeating Group, add the same pattern: a hidden group that becomes visible on hover, containing a Repeating Group of Categories where parent_category = current subcategory. Position this third-level dropdown to the right of the second-level dropdown (using Align to Parent with top-right). Each item in the third level should have a click workflow: Go to page → the Category's page_link. Apply this click workflow to second-level items as well for categories that are both clickable and have children.

**Expected result:** The menu supports three levels of navigation: top-level → subcategory → sub-subcategory, each revealed on hover.

### 6. Build a mobile hamburger menu with collapsible sections

Create a new group visible only on mobile breakpoints. Add a hamburger icon button (three horizontal lines). Add a custom state on the page called 'mobile_menu_open' (yes/no, default no). When the hamburger is clicked, toggle this state. Below the icon, add a full-width group visible only when mobile_menu_open is yes. Inside it, add a Repeating Group of top-level categories. Each cell has the category name plus a chevron icon. Add a custom state 'expanded_category' (Category type) on the page. When a cell is clicked, set expanded_category to Current cell's Category. Below the name, add a nested Repeating Group of subcategories, visible only when expanded_category = Current cell's Category.

**Expected result:** Mobile users see a hamburger menu that expands to show top-level categories, and tapping a category reveals its subcategories.

## Complete code example

File: `Workflow summary`

```text
MULTI-LEVEL MENU ARCHITECTURE
==============================

Data Type: Category
  Fields: name (text), slug (text), parent_category (Category),
          sort_order (number), page_link (text), icon (image)

Desktop Menu Structure:
  Reusable Element: NavBar
    Repeating Group (Row layout)
      Data source: Search Categories where parent_category is empty
      Sort: sort_order ascending
      Cell contents:
        Text: Current cell's Category's name
        Group Dropdown (not visible on page load)
          Conditional: When hovered → visible
          Repeating Group (Column layout)
            Data: Search Categories where parent = Parent group's Category
            Cell contents:
              Text: subcategory name
              Group Sub-dropdown (not visible, visible on hover)
                Repeating Group: sub-subcategories

Mobile Menu Structure:
  Custom States:
    Page → mobile_menu_open (yes/no, default: no)
    Page → expanded_category (Category, default: empty)
  
  Hamburger Button:
    Click → Set state mobile_menu_open = not mobile_menu_open
  
  Mobile Menu Group (visible when mobile_menu_open = yes):
    Repeating Group of top-level categories
      Click → Set expanded_category = Current cell's Category
      Nested RG of subcategories
        Visible when expanded_category = parent Category

Navigation Workflows:
  When menu item clicked → Go to page: Category's page_link
  OR → Go to page with data: send Category to detail page
```

## Common mistakes

- **Using nested searches inside Repeating Group cells for subcategories** — Each cell running its own 'Do a search for' multiplies database queries. With 10 top-level items, you make 10 separate searches for subcategories. Fix: Load all categories in one search at the page level and filter with constraints in each Repeating Group data source, or pre-load subcategories into a custom state list.
- **Dropdown menus disappearing before users can click them** — If there is a gap between the parent item and the dropdown group, the mouse leaves the hover zone and the dropdown hides. Fix: Ensure the dropdown group overlaps slightly with the parent element (no gap), or use a custom state with a small delay instead of pure hover visibility.
- **Not handling categories with no children in the dropdown** — An empty dropdown appears as a small styled box with no content, looking broken. Fix: Add a conditional on the dropdown group: 'When Do a search for Categories (parent = this Category):count is 0 → This element is not visible.'

## Best practices

- Use a self-referencing Category Data Type to support unlimited menu depth
- Add a sort_order field to control menu item positioning without editing design elements
- Build separate menu layouts for desktop (hover dropdowns) and mobile (collapsible sections)
- Use a reusable element for the menu so it appears consistently across all pages
- Hide empty dropdown groups when a category has no subcategories
- Pre-load category data to minimize database queries from nested Repeating Groups
- Add visual indicators (chevron icons) to show which items have submenus

## Frequently asked questions

### How many menu levels can I create?

Technically unlimited, since the parent-child structure supports infinite depth. However, for usability, stick to 2-3 levels. Deeper menus become difficult for users to navigate.

### Can I manage the menu from an admin panel?

Yes. Since the menu is database-driven, you can build an admin page where you create, edit, reorder, and delete categories. Changes will reflect in the menu automatically.

### How do I highlight the current page in the menu?

Add a conditional on each menu item: 'When Current Page name is this Category's page_link → text color is blue (or your highlight color).' This visually indicates the active page.

### Will a multi-level menu slow down my app?

If you load all categories with efficient searches and avoid nested queries per cell, the performance impact is minimal. For menus with 50+ items, consider using Option Sets instead of database categories for instant loading.

### Can I add icons to menu items?

Yes. Add an icon or image field to the Category Data Type. In the menu cell, place an Image element next to the text and set its source to Current cell's Category's icon.

### Can I get help building a complex navigation system?

Yes. RapidDev helps founders design and implement custom navigation architectures in Bubble, including mega menus, role-based menu visibility, and responsive mobile navigation patterns.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/create-a-multi-level-menu-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/create-a-multi-level-menu-in-bubble
