Search code examples
vue.jsnuxt.jsanchornuxt3.js

Nuxt.js 3 and on-site anchor navigation


I am learning Nuxt.js 3 and am writing a simple project with a one-scroll design that has a menu with anchor links. Clicking a link, the site should automatically scroll to the anchor (like a div with an id). To test this I set up a simple Nuxt 3 installation with npx nuxi init nuxt-app, removed the demo content and replaced it with this:

pages/index.vue

<template>
  <div>
    <div id="home"><p>hello world</p></div>
    <div class="menu">
      <nuxt-link :to="{ path: '/', hash: '#ciao' }">
        link
      </nuxt-link>
    </div>
    <div style="height: 3000px">placeholder</div>
    <div id="ciao"><p>ciao world</p></div>
    <div class="menu">
      <nuxt-link :to="{ path: '/', hash: '#home' }">
        link
      </nuxt-link>
    </div>
    <div style="height: 3000px">placeholder</div>
  </div>
</template>

The problem is, that it is not working. The url in the browser is changed to localhost:3000/#ciao or localhost:3000/#home on click. But the view is not being changed.

Is there something else I need to set up in nuxt, to get anchor navigation to work?


Solution

  • As answered here: https://github.com/nuxt/framework/discussions/5561#discussioncomment-3007717

    Using a regular a tag solves the issue

    <a href="/#ciao">
      go to ciao's hash
    </a>
    

    Otherwise, you can also use

    <nuxt-link :to="{ hash: '#home' }" :external="true"> <!-- no need for a path if same page -->
      go to home's hash
    </nuxt-link>
    

    The external prop (Nuxt3 only) is detailed here: https://v3.nuxtjs.org/api/components/nuxt-link#props

    Quote from the documentation

    Forces the link to be considered as external (true) or internal (false). This is helpful to handle edge-cases.