nuxt-anchorscroll 
nuxt-anchorscroll
This module provides scroll implementation (scroll to top and scroll to anchor element).
Originally it was intended for anchor scrolling that's why it's called nuxt-anchorscroll
Features
- Configured out of the box
- Supports both kinds of layouts*
- Extendable
Configured out of the box
- For top scroll - scroll instantly, until top with zero offset, ignore xaxis
- For anchor scroll - scroll smoothly, until top element with zero offset, ignore xaxis
- Surfaces - htmlandbodyelements
- General function - scroll to anchor if element exist (uses route.hashas selector), otherwise to top - respects page metanuxt-anchorscrolloptions
Supports both kinds of layouts*
In common case, you use cropped html or full html. In first case (you can check this now) scroll to anchor will not work. If it so, you can have a minimal setup.
But in case if anchor scroll is handled (by browser), you need additional setup - full explanation in module playground.
Extendable
Anchor scroll can be specified for needed route via matched field of NuxtApp.$anchorScroll
runtime configuration (default configuration setups before script setup)
nuxtApp.$anchorScroll!.matched.push(({ path, hash }) => {
  // Exit when route is not represent fixed example
  if (!path.startsWith('/standard/fixed'))
    return undefined
  if (hash) {
    // All anchor element on this route is mangled
    const targetSelector = `#fixed-${hash.slice(1)}`
    const targetElement = document.querySelector(targetSelector)
    if (targetElement) {
      return {
        toAnchor: {
          target: targetElement as HTMLElement,
          scrollOptions: toValue(useNuxtApp().$anchorScroll?.defaults?.toAnchor) ?? {},
        },
      }
    }
  }
})
Also your matched function can specify different surfaces for scrolling.
nuxtApp.$anchorScroll!.matched.push(({ path, hash }) => {
  // Exit when route is not represent fixed example
  if (!path.startsWith('/scrollable'))
    return undefined
  const surfaces = [...document.querySelectorAll('#exited-scrollable-surface')]
  return {
    toAnchor: {
      surfaces,
      scrollOptions: {
        /* ... */
      },
    },
    toTop: {
      surfaces,
      scrollOptions: {
        /* ... */
      },
    }
  }
})
Quick Setup
- Add nuxt-anchorscrolldependency to your project
Use your favorite package manager (I prefer yarn)
yarn add -D nuxt-anchorscroll
pnpm add -D nuxt-anchorscroll
npm install --save-dev nuxt-anchorscroll
- Add nuxt-anchorscrollto themodulessection ofnuxt.config.ts
export default defineNuxtConfig({
  modules: [
    'nuxt-anchorscroll',
  ]
})
- Additionally, if you are using transitions, probably you also want to scroll on different hook
export default defineNuxtConfig({
  modules: [
    'nuxt-anchorscroll',
  ],
  anchorscroll: {
    hooks: [
      // Or any valid hook if needed
      // Default is `page:finish`
      'page:transition:finish',
    ],
  },
})
- Additionally, if you using standard layout, see playground explanation.
That's it! You can now use nuxt-anchorscroll in your Nuxt app ✨
Composable
Most probably that you want to scroll to anchor ro to top on click. That's possible via useAnchorScroll composable
// Default to top is instant
const { scrollToAnchor, scrollToTop } = useAnchorScroll({
  toTop: {
    scrollOptions: {
      behavior: 'smooth',
      offsetTop: 0,
    }
  },
})
And use it in template
<template>
  <div
    class="box"
    mt-12
    flex flex-row gap-4 align-baseline
  >
    <h2
      :id="id"
      text-3xl font-extrabold
    >
      <slot />
    </h2>
    <NuxtLink
      :href="`#${id}`"
      mb-a mt-a
      text-xl
      @click="scrollToAnchor(id)"
    >
      #
    </NuxtLink>
  </div>
</template>