nuxt / nuxt/ui

`UNavigationMenu` issues with slots priority over rendered content

Open
#6,251 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
TypeScript
Stars
6.9k
Forks
1.1k
Avg merge
1d 7h
Merged PRs (30d)
57

Description

Environment
Operating system macOS 25.3.0
CPU Apple M4 Pro (12 cores)
Node.js version v24.13.0
nuxt/cli version 3.34.0
Package manager pnpm@10.32.1
Nuxt version 4.4.2
Nitro version 2.13.2
Builder vite@7.3.1
Config compatibilityDate, css, devtools, eslint, modules, routeRules
Modules @nuxt/eslint@1.15.2, @nuxt/ui@4.6.0
Is this bug related to Nuxt or Vue?

Nuxt

Package

v4.x

Version

4.6.0

Reproduction

https://github.com/TotomInc/nuxt-ui-repro/tree/repro/navigation-menu-slots (repro/navigation-menu-slots branch, not master)

Description

Scoped slots (#item-content and #item-trailing) on UNavigationMenu did not behave as expected: dropdown shell with viewport could appear with empty panels (nothing rendered), and custom trailing markup could still show default chevron icons.

item-content

Defining #item-content once (e.g. to customize the mega-menu body per item) caused every top-level item to be treated as having a dropdown.

Items without children still received NavigationMenuTrigger + NavigationMenuContent. If the slot rendered nothing for those rows (v-if="item.children"), the viewport still showed an empty data-slot="content" and empty childList.

item-trailing

Defining #item-trailing should give full control over the trailing area.

Instead, default chevrons (linkTrailingIcon) could still appear on rows where the slot intentionally rendered nothing, because defaults lived inside the same <slot> as fallback content, which interacted badly with createReusableTemplate / ReuseLinkTemplate for nested scoped slots.

Expected behavior

  • Dropdown trigger + content should only exist when an item actually has nested entries (children), unless the API explicitly adds another mechanism later.
  • When #item-trailing is provided, only that slot should render in the trailing region—no default badge/chevron mix-in for the same row.
Additional context

https://github.com/user-attachments/assets/1c548c72-fd2d-4fc6-876c-4c55cb135386

In the screen-recording, given the source-code of the repro, only the "V" dropdown + chevron should be visible, as this one has children content, while the others don't.

<template>
  <div>
    <UNavigationMenu :items="items">
      <template #item-trailing="{ item }">
        <span v-if="item.children">V</span>
      </template>

      <template #item-content="{ item }">
        <span v-if="item.children">More info...</span>
      </template>
    </UNavigationMenu>
  </div>
</template>
Logs

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked nuxt-ui-repro repository on the repro/navigation-menu-slots branch and inspect the UNavigationMenu slot implementation. Run the reproduction to observe item-content and item-trailing behavior, then verify that only items with children render dropdown content and that a provided trailing slot suppresses default icons.

Written by the indexing model from the issue text.

Assessment

Tech stack
nuxtjs, typescript
Domain
frontend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.