Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationNavigationmenu

Navigationmenu

A site-navigation menu whose triggers reveal panels of links.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Reka UI.

Installation

Complete project setup first. Your configuration must select vue/reka and include your Design System ID.

pnpm exec frontfriend download navigation-menu -f vue --primitive reka

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

<script setup lang="ts">
import { NavigationMenu } from "@/components/ui/navigation-menu";
import { NavigationMenuList } from "@/components/ui/navigation-menu";
import { NavigationMenuItem } from "@/components/ui/navigation-menu";
import { NavigationMenuTrigger } from "@/components/ui/navigation-menu";
import { NavigationMenuContent } from "@/components/ui/navigation-menu";
import { NavigationMenuLink } from "@/components/ui/navigation-menu";
import * as UI from "@/components/ui/navigation-menu";

const Component = UI.NavigationMenu;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <NavigationMenu
    ><NavigationMenuList
      ><NavigationMenuItem
        ><NavigationMenuTrigger>Components</NavigationMenuTrigger
        ><NavigationMenuContent
          ><NavigationMenuLink href="#"
            >Button</NavigationMenuLink
          ></NavigationMenuContent
        ></NavigationMenuItem
      ></NavigationMenuList
    ></NavigationMenu
  >
</template>

By default the panels animate inside a shared viewport that resizes to the active panel; :viewport="false" renders each panel in place instead. Both are covered below, since the viewport is what sizes and clips the content.

Subcomponents

  • NavigationMenu
  • NavigationMenuContent
  • NavigationMenuIndicator
  • NavigationMenuItem
  • NavigationMenuLink
  • NavigationMenuList
  • NavigationMenuTrigger
  • NavigationMenuViewport

Examples

Default

<script setup lang="ts">
import { NavigationMenu } from "@/components/ui/navigation-menu";
import { NavigationMenuList } from "@/components/ui/navigation-menu";
import { NavigationMenuItem } from "@/components/ui/navigation-menu";
import { NavigationMenuTrigger } from "@/components/ui/navigation-menu";
import { NavigationMenuContent } from "@/components/ui/navigation-menu";
import { NavigationMenuLink } from "@/components/ui/navigation-menu";
import { Icon } from "@/components/ui/icon";
import * as UI from "@/components/ui/navigation-menu";

const primitives = [
  {
    title: "Alert Dialog",
    href: "/docs/primitives/alert-dialog",
    description:
      "A modal dialog that interrupts the user with important content and expects a response.",
  },
  {
    title: "Hover Card",
    href: "/docs/primitives/hover-card",
    description:
      "For sighted users to preview content available behind a link.",
  },
  {
    title: "Progress",
    href: "/docs/primitives/progress",
    description:
      "Displays an indicator showing the completion progress of a task.",
  },
  {
    title: "Scroll-area",
    href: "/docs/primitives/scroll-area",
    description: "Visually or semantically separates content.",
  },
  {
    title: "Tabs",
    href: "/docs/primitives/tabs",
    description:
      "Layered sections of content — known as tab panels — displayed one at a time.",
  },
  {
    title: "Tooltip",
    href: "/docs/primitives/tooltip",
    description:
      "A popup that displays information related to an element on focus or hover.",
  },
];

const statuses = [
  { icon: "CircleHelp", label: "Backlog" },
  { icon: "Circle", label: "To Do" },
  { icon: "CircleCheck", label: "Done" },
];

const Component = UI.NavigationMenu;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <div class="flex h-[420px] w-[720px] items-start justify-center pt-4">
    <NavigationMenu v-bind="args">
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>Components</NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul class="grid w-[400px] gap-2 md:w-[500px] md:grid-cols-2">
              <li v-for="component in primitives" :key="component.title">
                <NavigationMenuLink :href="component.href">
                  <div class="text-sm font-medium">{{ component.title }}</div>
                  <p class="text-sm text-neutral-mid">
                    {{ component.description }}
                  </p>
                </NavigationMenuLink>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuTrigger>List</NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul class="grid w-[300px] gap-4">
              <li>
                <NavigationMenuLink href="#">
                  <div class="text-sm font-medium">Components</div>
                  <p class="text-sm text-neutral-mid">
                    Browse all components in the library.
                  </p>
                </NavigationMenuLink>
                <NavigationMenuLink href="#">
                  <div class="text-sm font-medium">Documentation</div>
                  <p class="text-sm text-neutral-mid">
                    Learn how to use the library.
                  </p>
                </NavigationMenuLink>
                <NavigationMenuLink href="#">
                  <div class="text-sm font-medium">Blog</div>
                  <p class="text-sm text-neutral-mid">
                    Read our latest blog posts.
                  </p>
                </NavigationMenuLink>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuTrigger>With Icon</NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul class="grid w-[200px] gap-4">
              <li>
                <NavigationMenuLink
                  v-for="status in statuses"
                  :key="status.label"
                  href="#"
                  class="flex-row items-center gap-2"
                >
                  <Icon :name="status.icon" />
                  {{ status.label }}
                </NavigationMenuLink>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuLink href="#">Docs</NavigationMenuLink>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  </div>
</template>

Without Viewport

<script setup lang="ts">
import { NavigationMenu } from "@/components/ui/navigation-menu";
import { NavigationMenuList } from "@/components/ui/navigation-menu";
import { NavigationMenuItem } from "@/components/ui/navigation-menu";
import { NavigationMenuTrigger } from "@/components/ui/navigation-menu";
import { NavigationMenuContent } from "@/components/ui/navigation-menu";
import { NavigationMenuLink } from "@/components/ui/navigation-menu";
import { Icon } from "@/components/ui/icon";
import * as UI from "@/components/ui/navigation-menu";

const statuses = [
  { icon: "CircleHelp", label: "Backlog" },
  { icon: "Circle", label: "To Do" },
  { icon: "CircleCheck", label: "Done" },
];

const Component = UI.NavigationMenu;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <div class="flex h-[320px] w-[520px] items-start justify-center pt-4">
    <NavigationMenu :viewport="false">
      <NavigationMenuList>
        <NavigationMenuItem>
          <NavigationMenuTrigger>Simple</NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul class="grid w-[200px] gap-4">
              <li>
                <NavigationMenuLink href="#">Components</NavigationMenuLink>
                <NavigationMenuLink href="#">Documentation</NavigationMenuLink>
                <NavigationMenuLink href="#">Blocks</NavigationMenuLink>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
        <NavigationMenuItem>
          <NavigationMenuTrigger>With Icon</NavigationMenuTrigger>
          <NavigationMenuContent>
            <ul class="grid w-[200px] gap-4">
              <li>
                <NavigationMenuLink
                  v-for="status in statuses"
                  :key="status.label"
                  href="#"
                  class="flex-row items-center gap-2"
                >
                  <Icon :name="status.icon" />
                  {{ status.label }}
                </NavigationMenuLink>
              </li>
            </ul>
          </NavigationMenuContent>
        </NavigationMenuItem>
      </NavigationMenuList>
    </NavigationMenu>
  </div>
</template>

Simple

<script setup lang="ts">
import { NavigationMenu } from "@/components/ui/navigation-menu";
import { NavigationMenuList } from "@/components/ui/navigation-menu";
import { NavigationMenuItem } from "@/components/ui/navigation-menu";
import { NavigationMenuLink } from "@/components/ui/navigation-menu";
import * as UI from "@/components/ui/navigation-menu";

const Component = UI.NavigationMenu;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <div class="flex w-[420px] justify-center py-6">
    <NavigationMenu>
      <NavigationMenuList>
        <NavigationMenuItem
          ><NavigationMenuLink href="#"
            >Home</NavigationMenuLink
          ></NavigationMenuItem
        >
        <NavigationMenuItem
          ><NavigationMenuLink href="#"
            >Docs</NavigationMenuLink
          ></NavigationMenuItem
        >
        <NavigationMenuItem
          ><NavigationMenuLink href="#"
            >Pricing</NavigationMenuLink
          ></NavigationMenuItem
        >
      </NavigationMenuList>
    </NavigationMenu>
  </div>
</template>

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.

NavigationMenu

Prop Type Default Description
class HTMLAttributes["class"] —
viewport boolean —

NavigationMenuContent

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuIndicator

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuItem

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuLink

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuList

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuTrigger

Prop Type Default Description
class HTMLAttributes["class"] —

NavigationMenuViewport

Prop Type Default Description
class HTMLAttributes["class"] —

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.