Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

NavMenu

A list of links that marks the current page.

A static page with IzzyBlazor's script. No circuit.

Usage

razor
<AppSidebar>
    <NavMenu>
        <NavItem Href="/" Icon="Lucide.House">Home</NavItem>
        <NavItem Href="/projects" Icon="Lucide.Folder">Projects</NavItem>
        <NavItem Href="/inbox" Icon="Lucide.Inbox" Badge="4">Inbox</NavItem>
        <NavDivider />
        <NavItem Href="/settings" Icon="Lucide.Settings">Settings</NavItem>
    </NavMenu>
</AppSidebar>

A nav menu is a list of links that marks the one for the current page. It works the same on static and interactive pages, with or without JavaScript: the server works out the current page from the address.

Organizing a sidebar

Use NavLabel to name a section of links, NavGroup to fold some away, NavDivider for a line between sections, and Badge on an item for a count or a label.

Code

Sidebar.razor
@inject NavigationManager Navigation

@* A sidebar's links: NavLabel names a section, NavGroup folds items away (a details element, so it
   opens with no script), NavDivider separates, and Badge adds a count. The item for the current
   page is marked on the server. *@
<Box As="nav" aria-label="Main" Width="Length.Rem(16)" MaxWidth="Length.Full">
    <NavMenu>
        <NavLabel>Workspace</NavLabel>
        <NavItem Href="@To(null)" Icon="Lucide.LayoutDashboard">Dashboard</NavItem>
        <NavItem Href='@To("inbox")' Icon="Lucide.Inbox" Badge="12" BadgeAccent="Accent.Primary">Inbox</NavItem>
        <NavGroup Label="Projects" Icon="Lucide.Folder" Open>
            <NavItem Href='@To("projects/website")'>Website</NavItem>
            <NavItem Href='@To("projects/course")'>Course app</NavItem>
        </NavGroup>
        <NavDivider />
        <NavItem Href='@To("billing")' Icon="Lucide.CreditCard" Badge="New" BadgeStatus="Status.Success">Billing</NavItem>
        <NavItem Href='@To("settings")' Icon="Lucide.Settings">Settings</NavItem>
    </NavMenu>
</Box>

@code {
    // Links that stay on this page: ?view= in its address (a key of its own: the other examples on
    // the page use others).
    private string To(string? page) => Navigation.GetUriWithQueryParameter("view", page);
}

A group is a native details element, so it opens and closes with no script. Open starts it open, and ActivePrefix opens it on the pages at or below a path, such as /projects; with the script, a group holding the current page opens itself too.

The current page

Use Match to say how the address must match an item's Href: by default an item is current on its page and the pages below it, and NavLinkMatch.All makes it current on its own page only.

razor
@* Current on /projects and on /projects/42 *@
<NavItem Href="/projects">Projects</NavItem>

@* Current on /reports only *@
<NavItem Href="/reports" Match="NavLinkMatch.All">Reports</NavItem>

@* Current on /inbox, unless Starred is *@
<NavItem Href="/inbox">Inbox</NavItem>
@* Current on /inbox?view=starred *@
<NavItem Href="/inbox?view=starred">Starred</NavItem>

A link to the app's root (/) is only ever current on the home page, and a link with a query string only when the query is the same. Of links to one page told apart by the query, as Inbox and Starred are, one is current at a time: the link without a query gives way when one with a query matches, as Dashboard does in the sidebar example when another item is picked.

Badges and counts

Use BadgeVariant.Plain for quiet totals with no fill, as docs and mail sidebars show them; BadgeAccent gives a badge a color of its own, such as Accent.Primary for an unread count, and BadgeStatus a status's color.

Code

Counts.razor
@inject NavigationManager Navigation

@* BadgeVariant.Plain shows quiet totals with no fill, as docs and mail sidebars do. Long labels
   wrap rather than being cut off. *@
<Box As="nav" aria-label="Guide" Width="Length.Rem(16)" MaxWidth="Length.Full">
    <NavMenu>
        <NavLabel>Get started</NavLabel>
        <NavItem Href="@To(null)">Install</NavItem>
        <NavItem Href='@To("guide/existing-layout")'>Add it to an app that already has its own layout</NavItem>
        <NavLabel>Components</NavLabel>
        <NavItem Href='@To("guide/forms")' Badge="12" BadgeVariant="BadgeVariant.Plain">Forms</NavItem>
        <NavItem Href='@To("guide/overlays")' Badge="7" BadgeVariant="BadgeVariant.Plain">Overlays</NavItem>
        <NavItem Href='@To("guide/data")' Badge="9" BadgeVariant="BadgeVariant.Plain">Data display</NavItem>
    </NavMenu>
</Box>

@code {
    // Links that stay on this page: ?doc= in its address (a key of its own: the other examples on
    // the page use others).
    private string To(string? page) => Navigation.GetUriWithQueryParameter("doc", page);
}

Long labels wrap rather than being cut off.

Use Orientation="Orientation.Horizontal" for a row of section links, such as a project's pages; when they don't fit, as on a phone, the row scrolls sideways.

Code

Horizontal.razor
@inject NavigationManager Navigation

@* Orientation.Horizontal lays the items in a row, for a bar of section links. *@
<nav aria-label="Project">
    <NavMenu Orientation="Orientation.Horizontal">
        <NavItem Href="@To(null)">Overview</NavItem>
        <NavItem Href='@To("deploys")'>Deploys</NavItem>
        <NavItem Href='@To("logs")' Badge="3" BadgeStatus="Status.Danger">Logs</NavItem>
        <NavItem Href='@To("settings")'>Settings</NavItem>
    </NavMenu>
</nav>

@code {
    // Links that stay on this page: ?tab= in its address (a key of its own: the other examples on
    // the page use others).
    private string To(string? page) => Navigation.GetUriWithQueryParameter("tab", page);
}

For a site's main links in the header, which fold into a menu on phones, use a SiteNav: it takes the same NavItems.

In a landmark

A nav menu is a list, not a landmark: put it in an AppSidebar, which is a nav named "Main", or in a nav element with its own aria-label, as the examples do. Use HiddenFrom or VisibleFrom on an item to show it only on some screens; they hide the whole list item.

Parts

Written inside NavMenu. The API page lists their parameters.

  • NavItem: one navigation link.
  • NavGroup: a collapsible group of nav items, built on <details>, so it opens and closes with no JavaScript.
  • NavLabel: a small heading that labels the items below it in a NavMenu: a plain list item, since a list holds only items.
  • NavDivider: a line between groups of items in a NavMenu.

Mode support

What works in each mode, NavMenu
FeatureOffStaticLive
EverythingYesYesYes

Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).

Accessibility

  • It renders a ul of links, not a landmark: put it in an AppSidebar (a nav named "Main") or in a nav with its own aria-label.
  • The active item has aria-current="page"; an item above the current page (Match Prefix) gets aria-current="true", so screen readers hear one current page. Of links to one page told apart by the query (?view=starred), only one is current.
  • A NavGroup is a native details, so Enter and Space open and close it with no script; with script, a group holding the current page opens itself.
  • NavLabel is a plain list item, read as text before the links under it, not a heading or a group name; NavDivider is hidden from screen readers, as a list holds only items.

Parameters

NavMenu parameters
PropTypeDefault
OrientationVertical for sidebars (the default), horizontal for header bars.OrientationOrientation.Vertical
ChildContentThe items: NavItem, NavGroup, NavLabel, NavDivider.RenderFragment?

See also

  • AppSidebar: a sidebar that becomes a drawer or panel on small screens.
  • SiteNav: header links that fold into a menu on phones.
  • Tabs: panels that switch with no script, or links to pages.
  • Breadcrumb: the path to the current page.