nuxt: Nuxt Link does not scroll to top on new page...

Environment

  • Operating System: Darwin
  • Node Version: v19.1.0
  • Nuxt Version: 3.1.1
  • Nitro Version: 2.1.0
  • Package Manager: yarn@1.22.19
  • Builder: vite
  • User Config: runtimeConfig, pages, modules, plugins, build, googleFonts, i18n, strapi, vite
  • Runtime Modules: @nuxtjs/tailwindcss@6.3.0, @nuxtjs/google-fonts@3.0.0-1, @nuxtjs/strapi@1.7.1, @nuxtjs/i18n@8.0.0-beta.9
  • Build Modules: -

Reproduction

Simply add normal <NuxtLink :to"newPage"></NuxtLink> or in my situation with i18n : <NuxtLink :to="localePath({ name: newPage })"></NuxtLink>

Describe the bug

Hi, I know this was already added in bugs, but none of solutions I found here worked for me… When clicking a classical NuxtLink, page does not scroll to top.

Solutions I found and tried but not working :

Plugin use : /plugins/router.ts

import { defineNuxtPlugin } from "#app";

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.$router.options.scrollBehavior = () => {
    return { left: 0, top: 0 };
  };
});

Middleware use : /middleware/route.global.ts

export default defineNuxtRouteMiddleware((to, from) => {
  useNuxtApp().hook("page:finish", () => {
    if (history.state.scroll) {
      setTimeout(() => window.scrollTo(history.state.scroll), 0);
    } else {
      setTimeout(() => window.scrollTo(0, 0), 0);
    }
  });
});

And finally router options use : /app/router.options.ts

import type { RouterConfig } from "@nuxt/schema";

export default <RouterConfig>{
  scrollBehavior(to, _from, savedPosition) {
    return new Promise((resolve, _reject) => {
      setTimeout(() => {
        if (savedPosition) {
          resolve(savedPosition);
        } else {
          if (to.hash) {
            resolve({
              el: to.hash,
              top: 80,
            });
          } else {
            resolve({ top: 0 });
          }
        }
      }, 100);
    });
  },
};

or :

import type { RouterOptions } from "@nuxt/schema";

export default <RouterOptions>{
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    } else {
      return {
        top: 0,
        behavior: "smooth",
      };
    }
    return { top: 0 };
  },
};

Non of these solutions are working and page never goes top after nuxt link click.

Additional context

No response

Logs

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 6
  • Comments: 19 (9 by maintainers)

Most upvoted comments

I found this code on nuxt/movies. I hope it help.

nuxt/movies@20a859b

I have this problem too, but in my case ‘page:transition:finished’ didn’t fix the problem, but ‘page:finished’ did

I wrote next plugin which scrolls page to top. It simulates definePageMeta({ scrollToTop: true }) behaviour. So all is you need is to install this plugin and use definePageMeta as usual. In some case, you can change hook to transition (which is not works for me but may be for you), or set similar code on different hooks

// scroll.client.ts
export default defineNuxtPlugin({
  name: 'scroll-client',
  hooks: {
    'page:finish': () => {
      if (!useRouter().currentRoute.value.meta.scrollToTop)
        return

      document.scrollingElement?.scrollTo({ left: 0, top: 0 })
      document.body?.scrollTo({ left: 0, top: 0 })
    },
  },
})

I don’t really expected that Nuxt will be such broken :(

  • Hope that 3.6.0 will release as soon as possible, because as I understand definePageMeta is fixed there

CSS scroll-behavior: smooth; Can cuse this behavior

@danielroe this issue does seem to be an issue when the CSS for smooth-scrolling is set:

html { scroll-behavior:smooth; }

If you set this, it causes NuxtLink to do weird things on new routes, setting the scroll depth of the resulting page to the value of the originating page. I really think Nuxt should fix this issue as it causes a serious usability problem. I’ve looked at this problem on various sites since Nuxt 2.0 and didn’t realize the problem was so basic.

Thank you @fos7er for the insight!

It’d be great if someone could attach a StackBlitz or CodeSandbox as reproduction 👍🏻

For me does not work neither.

See my comment above please ☺️