`UNavigationMenu` issues with slots priority over rendered content
Nobody has claimed this yet.
- 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-trailingis 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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