Skip to content

Nuxt 3/Nuxt UI UNavigationMenu won’t highlight hash‐based section on page reload #4416

Open
@Aravinda93

Description

@Aravinda93

Environment

"nuxt": "^3.17.5",
"@nuxt/ui": "^3.1.3",

Is this bug related to Nuxt or Vue?

Nuxt

Version

3.1.3

Reproduction

Following is my components/AppHeader.vue:

<template>
  <header class="bg-white sticky top-0 z-50">
    <nav class="hidden lg:flex flex-1 justify-center">
      <UNavigationMenu
        v-model="activeSection"
        :items="navItems"
        class="space-x-2"
        highlight
        highlight-color="primary"
      >
        <template #item="{ item, active }">
          <ULink
            as-child
            :to="{ path: '', hash: `#${item.to}` }"
            exact-hash
            class="px-4 py-2 rounded-md transition"
            aria-label="Go to {{ item.label }}"
          >
            <span class="inline-flex items-center">
              <UIcon v-if="item.icon" :name="item.icon" class="size-5 mr-2" />
              <span>{{ item.label }}</span>
            </span>
          </ULink>
        </template>
      </UNavigationMenu>
    </nav>
  </header>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import { useRoute } from "vue-router";
import type { NavigationMenuItem } from "@nuxt/ui";

const route = useRoute();
const activeSection = ref("");

// Define your nav data (to = hash without leading '#')
const navItems = ref<NavigationMenuItem[]>([
  { label: "Home", icon: "i-lucide-home", value: "", to: "" },
  {
    label: "About Us",
    icon: "i-lucide-user-circle",
    value: "about",
    to: "about",
  },
  {
    label: "Products",
    icon: "i-lucide-package",
    value: "products",
    to: "products",
  },
  {
    label: "Technologies",
    icon: "i-lucide-cpu",
    value: "technologies",
    to: "technologies",
  },
  {
    label: "News",
    icon: "i-lucide-newspaper",
    value: "news",
    to: "news",
  },
]);

// On load, seed activeSection from the current hash
onMounted(() => {
  activeSection.value = route.hash.replace(/^#/, "");
});

// Update when the hash changes
watch(
  () => route.hash,
  (h) => {
    activeSection.value = h.replace(/^#/, "");
  }
);
</script>

Description

I’m using the Nuxt UI <UNavigationMenu> component in my Nuxt 3 app to render a header nav that scrolls to sections via hash links within my pages/index.vue (#about, #products, #news, etc.). Clicking works fine, and the correct menu item highlights and scrolls to that section.

However, if I reload the page while viewing, for example,/#products or any other section like #news, #about, etc., the page scrolls to the respective products/news/about section, but the navigation menu always highlights “Home” (the first item) instead of Products/News/About.

How can I get <UNavigationMenu> to pick up the current route.hash on load so that the correct item is active?

Following is the documentation I am refeering to:
API: https://ui.nuxt.com/components/navigation-menu

Additional context

No response

Logs

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingv3#1289

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions