Skip to content

UNavigationMenu issues with slots priority over rendered content #6251

@TotomInc

Description

@TotomInc

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 [email protected]
Nuxt version 4.4.2
Nitro version 2.13.2
Builder [email protected]
Config compatibilityDate, css, devtools, eslint, modules, routeRules
Modules @nuxt/[email protected], @nuxt/[email protected]

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

CleanShot.2026-03-27.at.16.22.05.mp4

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriageAwaiting initial review and prioritizationv4#4488

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions