DEV Community

Cover image for Building a Mega Menu and Menu Builder
SIRAJ GADHIA
SIRAJ GADHIA

Posted on

Building a Mega Menu and Menu Builder

Building a Mega Menu and Menu Builder UI in Blazor Server (.NET 9)

In this two-part blog series, I’ll walk you through building a dynamic, data-driven Mega Menu in a Blazor Server project, and then a powerful visual JSON builder to manage it. Both parts are built with modern technologies, including .NET 9, Blazor Server, Bootstrap, and Font Awesome, with zero API calls and completely client-side logic.


PART I:

Let's Develop a Mega Menu Blazor Component

Goals

✅ Create a dynamic Mega Menu using a JSON data structure.
✅ No API calls – file-based configuration - Pure CSS.
✅ Style it using Bootstrap and Font Awesome.
✅ Structure menu data with a POCO model and load it in Blazor.
✅ Build a reusable component (NavMegaMenu360.razor) to render the Mega Menu.
✅Lightweight, isolated, and drop-in ready for any Blazor navigation layout.
🚧 Set the stage for a follow-up Menu Builder UI with real-time editing.

Technology Used

  • Blazor Server (.NET 9 Preview)
  • Bootstrap 5 for layout
  • Font Awesome 6 for menu icons
  • C# POCO classes for menu structure
  • JSON for storing and editing menu content

How We Achieved This

Mega Menu Wireframe

We built a dynamic Blazor component that loads a menu-test.json file and binds the data to generate a structured Mega Menu UI.

Step-by-Step

  1. Defined POCO classes for TopLinks, Groups, and Items (with UUIDs for identity).
  2. Loaded JSON file directly using Http.GetFromJsonAsync – no controller/API.
  3. Styled menu using Bootstrap grid system and icons via Font Awesome.
  4. Rendered the menu in a reusable .razor component that you can drop into your layout.

Step 1: POCO Structure for Menu

We define 3 classes: MegaMenuTopLink, MegaMenuGroup, and MegaMenuItem, each with a unique Guid to support editing and tracking.

public class MegaMenuTopLink
{
    public Guid TopLinkID { get; set; } = Guid.NewGuid();
    public string Name { get; set; }
    public string Icon { get; set; }
    public string RightOffset { get; set; } // optional
    public List<MegaMenuGroup> Groups { get; set; } = new();
}

public class MegaMenuGroup
{
    public Guid GroupID { get; set; } = Guid.NewGuid();
    public List<MegaMenuItem> Items { get; set; } = new();
}

public class MegaMenuItem
{
    public Guid ItemID { get; set; } = Guid.NewGuid();
    public string Type { get; set; } // link, title, separator, image
    public string Text { get; set; }
    public string Url { get; set; }
    public string Icon { get; set; }
    public string Class { get; set; }
    public string Src { get; set; } // For image type
    public string Alt { get; set; } // For image accessibility
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Sample JSON Structure

[
  {
    "topLinkID": "...",
    "name": "Dashboard",
    "icon": "fa fa-gauge",
    "groups": [
      {
        "groupID": "...",
        "items": [
          {
            "itemID": "...",
            "type": "title",
            "text": "Reports",
            "icon": "fa fa-chart-bar",
            "class": "text-primary"
          },
          {
            "itemID": "...",
            "type": "link",
            "text": "Sales",
            "url": "/sales",
            "icon": "fa fa-dollar-sign"
          }
        ]
      }
    ]
  }
]
Enter fullscreen mode Exit fullscreen mode

Step 3: Load JSON in Blazor Component

Inside NavMegaMenu360.razor, we load menu-test.json using HttpClient:

protected override async Task OnInitializedAsync()
{
    try
    {
        var url = new Uri(new Uri(NavManager.BaseUri), "menu-test.json").ToString();
        MenuLinks = await Http.GetFromJsonAsync<List<MegaMenuTopLink>>(url);
    }
    catch (Exception ex)
    {
        ErrorMessage = $"Error loading menu.json: {ex.Message}";
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Key UI Component – NavMegaMenu360.razor

This Razor component generates the Mega Menu layout using Bootstrap and loops over menu data.

<ul class="mega-menu-nav">
    @foreach (var topLink in MenuLinks)
    {
        <li class="top-link-item">
            <a href="#"><i class="@topLink.Icon"></i> @topLink.Name</a>
            <div class="dropdown mega-dropdown">
                <div class="dropdown-content m-3">
                    @foreach (var group in topLink.Groups)
                    {
                        <div class="dropdown-col">
                            @foreach (var item in group.Items)
                            {
                                @switch (item.Type?.ToLower())
                                {
                                    case "title":
                                        <h5 class="dropdown-title @item.Class">
                                            <i class="@item.Icon"></i> @item.Text
                                        </h5>
                                        break;
                                    case "link":
                                        <a href="@item.Url" class="dropdown-link @item.Class">
                                            <i class="@item.Icon"></i> @item.Text
                                        </a>
                                        break;
                                    case "separator":
                                        <hr class="dropdown-separator" />
                                        break;
                                    case "image":
                                        <img src="@item.Src" alt="@item.Alt" />
                                        break;
                                }
                            }
                        </div>
                    }
                </div>
            </div>
        </li>
    }
</ul>
Enter fullscreen mode Exit fullscreen mode

Styling (Embedded CSS)

.mega-dropdown {
    position: absolute;
    display: none;
    background-color: #e6f9ff;
    z-index: 9999;
    border-radius: 4px;
}

.top-link-item:hover > .mega-dropdown {
    display: flex;
    padding: 1rem;
}

.dropdown-content {
    display: flex;
    gap: 2rem;
}

.dropdown-title {
    font-weight: bold;
    margin-bottom: 0.5rem;
}

.dropdown-separator {
    border-top: 1px solid #007399;
}
Enter fullscreen mode Exit fullscreen mode

What We've Achieved in Part I

  • A clean and customizable Mega Menu using POCO + JSON
  • Reusable and dynamic Blazor component
  • CSS-powered hover dropdown logic
  • Font Awesome icons per menu item
  • Ready for next step: Visual Builder and Live Preview

End Result

A clean mega menu that can be configured just by editing a JSON file, with support for sections, items, icons, links, separators, and more.

Screenshots of the End Result

Mega Menu Screenshot

Enhancements You Can Add

  • Add support for nested submenus.
  • Animate hover transitions.
  • Introduce role-based visibility or authentication.
  • Add client-side caching.

Source Files

The full repo is available at:

github.com/Siraj360/MegaMenu/tree/main

the Mega Menu component NavMegaMenu360.razor is available in a Git repository.

Drop them into your Blazor project, include a sample menu.json', modify themenu.json` file as per your needs, and you’re ready to go!


Final Note

This mega menu component is versatile - it can also function as a simple, traditional dropdown menu. To achieve this, just include one group per TopLink. When configured this way, the menu renders in a single-column layout, resembling a standard dropdown menu rather than a multi-column mega menu.


What’s Next – Mega Menu Builder (Part II)

In the upcoming Part II, we will:

  • Build a full Visual Mega Menu Builder UI in Blazor
  • Enable adding, deleting, and editing:
    • TopLinks
    • Groups
    • Menu Items
  • Bind controls directly to JSON data
  • Enable Live Preview of Mega Menu and JSON output
  • Use Bootstrap cards, tables, modals, and Font Awesome
  • Add a “Save to JSON File” button with real persistence

Stay tuned!

👉 Don't miss Part II – where you can build your Mega Menu visually!

I would love to hear your feedback or ideas — drop a comment with suggestions or enhancements you’d like to see.

Let’s build beautiful, maintainable, dynamic navigation together – powered by Blazor.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.