Skip to content
IzzyBlazor 0.1.0-alpha.17

Enter all results ↑ ↓ move Esc close

SiteNav

Header links that fold into a menu on phones.

JavaScript off: what the HTML and CSS do on their own.

Usage

razor
<AppShell Variant="ShellVariant.Flat">
    <AppHeader>
        <AppBrand Href="/" Icon="Lucide.Zap" Label="Acme" />
        <Box Grow />
        <SiteNav>
            <NavItem Href="/projects">Projects</NavItem>
            <NavItem Href="/articles">Articles</NavItem>
            <NavItem Href="/about">About</NavItem>
        </SiteNav>
    </AppHeader>
    <AppMain>@Body</AppMain>
</AppShell>

A site nav is a row of links in an AppShell's header, for a site with no sidebar. Its links are NavItems, marked current on the server as in a NavMenu.

Use Breakpoint for the width below which the links fold into a menu button that opens them in a panel under the header, 768px by default; the same button closes it, so the header with the site's name stays in view.

Preview width

Preview

Code

ContentSite.razor
@inject NavigationManager Navigation

@* A content site with no sidebar. SiteNav is a row of links in the header from 768px up; below it
   a menu button opens the same links in a panel under the header, with SiteNavFooter's button
   at the bottom. *@
<AppShell Variant="ShellVariant.Flat" ContentWidth="Length.Rem(72)">
    <AppHeader>
        <AppBrand Href="@To(null)" Icon="Lucide.Zap" Label="Acme Labs" />
        <Box Grow />
        <SiteNav>
            <NavItem Href="@To(null)">Projects</NavItem>
            <NavItem Href='@To("articles")'>Articles</NavItem>
            <NavItem Href='@To("guides")'>Guides</NavItem>
            <SiteNavFooter>
                <Button Href='@To("watch")' StartIcon="Lucide.Play" FullWidth>Watch the series</Button>
            </SiteNavFooter>
        </SiteNav>
        <IconButton Icon="Brands.GitHub" Label="GitHub" Href="https://github.com" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral" />
    </AppHeader>

    <AppMain>
        <Section Spacing="SectionSpacing.Lg">
            <Stack Gap="5" MaxWidth="Length.Rem(40)">
                <Row><Badge Status="Status.Info">New series</Badge></Row>
                <Heading Level="1" Size="TextSize.Xl5" MinSize="TextSize.Xl3">Build real apps, one commit at a time</Heading>
                <TextBlock Size="TextSize.Lg" Color="Color.Muted">Every episode ships a working feature. Watch the change, read the diff, and run the code at that exact step.</TextBlock>
                <Row Gap="3" Wrap>
                    <Button Href='@To("watch")' StartIcon="Lucide.Play" Size="ControlSize.Lg">Watch the series</Button>
                    <Button Href="@To(null)" Variant="ButtonVariant.Outline" Accent="Accent.Neutral" Size="ControlSize.Lg">Browse projects</Button>
                </Row>
            </Stack>
        </Section>
        <Section Bg="Color.FillSubtle">
            <Grid MinChildWidth="Length.Rem(16)" Gap="4">
                <Card Title="Rulebook console" Description="A rules engine admin, from empty repo to deployed." Href='@To("projects/rulebook")' />
                <Card Title="Invoice kit" Description="Billing with PDFs, email and a customer portal." Href='@To("projects/invoices")' />
                <Card Title="Field notes" Description="An offline-first notes app with sync." Href='@To("projects/field-notes")' />
            </Grid>
        </Section>
    </AppMain>

    <AppFooter>
        <Row Gap="4" Align="Align.Center" Wrap>
            <TextBlock Size="TextSize.Sm" Color="Color.Muted" Grow>© 2026 Acme Labs</TextBlock>
            <TextBlock As="span" Size="TextSize.Sm"><Anchor Href='@To("about")'>About</Anchor></TextBlock>
            <TextBlock As="span" Size="TextSize.Sm"><Anchor Href='@To("sponsors")'>Sponsors</Anchor></TextBlock>
        </Row>
    </AppFooter>
</AppShell>

@code {
    // Links within this example: ?view= in its own address, so they stay here.
    private string To(string? page) => Navigation.GetUriWithQueryParameter("view", page);
}

Off: At phone width the menu button opens the links in a native popover; focus stays on the button.

The panel is a native popover, so it opens and closes with JavaScript off, and Escape or a tap outside closes it. With the script, opening it moves focus to the first link, and following a link closes it.

Use SiteNavFooter for what goes under the links in the panel, such as the content site's "Watch the series" button; it shows on phones only, in the panel.

razor
<SiteNav>
    <NavItem Href="/projects">Projects</NavItem>
    <NavItem Href="/articles">Articles</NavItem>
    <SiteNavFooter>
        <Button Href="/signup" FullWidth>Sign up</Button>
    </SiteNavFooter>
</SiteNav>

On wide screens the footer isn't shown, so put anything people need there too elsewhere on the page as well, as the content site's hero repeats its button.

With a sidebar

Put a site nav in the header of a shell with an AppSidebar for links to the rest of the site beside the app's own: on phones its menu button stays hidden and the links show at the top of the sidebar's drawer or panel instead, so there's one menu.

razor
<AppShell>
    <AppHeader>
        <SidebarToggle />
        <AppBrand Href="/" Icon="Lucide.Zap" Label="Acme" />
        <Box Grow />
        <SiteNav>
            <NavItem Href="/guide">Guide</NavItem>
            <NavItem Href="/blog">Blog</NavItem>
        </SiteNav>
    </AppHeader>
    <AppSidebar>
        <NavMenu>...</NavMenu>
    </AppSidebar>
    <AppMain>@Body</AppMain>
</AppShell>

The guide demo has site links over a sidebar of chapters.

Where the menu button goes

On phones the menu button sits at the end of the header, where people look for it, whatever comes after the links; set MenuButtonPosition to Start to put it before the brand, as on pages whose header starts with a SidebarToggle, or to InPlace to leave it where the links are.

Its own words

Use Label for the navigation landmark's name ("Site", so it differs from a sidebar's "Main") and MenuLabel for the menu button's ("Menu").

Parts

Written inside SiteNav. The API page lists their parameters.

  • SiteNavFooter: content under the links in a SiteNav's panel, shown below its breakpoint only: social links, a color scheme switch, a call to action.

Mode support

What works in each mode, SiteNav
FeatureOffStaticLive
A row of links from the breakpoint upYesYesYes
A menu button on phones; Escape or a tap outside closes the panelYesYesYes
Focus moves to the first link when the panel opensNoYesYes
The links move into an AppSidebar on phonesYesYesYes

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

Accessibility

  • The links are in a nav landmark named "Site" (Label); in an AppShell with an AppSidebar, the copy shown on small screens is in the sidebar's "Main" instead.
  • The links render more than once, but only one copy shows at a time, so screen readers meet them once.
  • The menu button is a native button named "Menu" (MenuLabel) that opens a native popover: the browser reports whether it's open, and Escape or a tap outside closes it, with no script.
  • With JavaScript, opening moves focus to the first link, and following a link closes the panel.
  • The panel doesn't trap focus: Tab can move past its last link to the rest of the page.

Parameters

SiteNav parameters
PropTypeDefault
ChildContentThe links: NavItem, plus NavDivider or NavLabel, and any SiteNavFooter.RenderFragment?
BreakpointBelow this width the links fold into the menu button.BreakpointBreakpoint.Md
LabelThe navigation landmark's name for screen readers.string?computed
MenuLabelThe menu button's name.string?computed
MenuButtonPositionWhere the menu button sits in the header on small screens: MenuButtonPosition.End (the default), after everything else; MenuButtonPosition.Start, before the brand, to match pages whose header starts with a SidebarToggle; or MenuButtonPosition.InPlace, where the links are.MenuButtonPositionMenuButtonPosition.End
IdThe panel's id.string?

See also

  • NavMenu: a list of links that marks the current page.
  • AppSidebar: a sidebar that becomes a drawer or panel on small screens.
  • AppShell: header, sidebar, main area, aside and footer, arranged by CSS.
  • Menu: links, form posts and actions in a popover menu.
  • Demos: Content site.