Nuxt.js: scrollBehavior Glitches

Created on 14 Aug 2017  Â·  58Comments  Â·  Source: nuxt/nuxt.js

Hi. We have various issues reported for scrollBehavior not behaving as desired. Maybe use-cases differ but almost all of them are related to the same known issue and we are aware and plan to help fixing it. Please don't make/reopen duplicated issues as there is enough info about the problem.It just makes the process harder. As of always contributions and PRs are appreciated to both vue-router and nuxt for possible fixes.

vue-router

  • Handle scrollBehaviour with transitions (vuejs/vue-router#1263)
  • Another detail of scrollBehavior wrapped in transition(vuejs/vue-router#1373)
  • scrollBehavior doesn't work for initial route in Firefox (vuejs/vue-router#1585)
  • Need a way to set what scroll position is saved (vuejs/vue-router#1187)
  • Navigating back should retain the scroll position. (vuejs/vue-router#1669)
  • Support parent container for scroll behavior (vuejs/vue-router#1249)
  • Calcurated scroll position is incorrect in some browser with animation (vuejs/vue-router#1530)

Issues

  • Strange behavior in Firefox browser when page transition (#1373)
  • What causes a glitch when page transition in Firefox? (#1002)
  • Delayed scroll top possible? (#1355)
  • ScrollBehavior: Fires too early (#1036)
  • Navigating back should retain the scroll position. (#1182)

Reproductions

Misc

This bug report is available on Nuxt.js community (#c1219)
available soon bug-confirmed

Most helpful comment

I just implemented the new scrollBehavior with window.history.scrollRestoration, and it works like a charm, thank you everyone to your big help on this difficult issue, big thank you to @homerjam who made a fix to vue-router!

I'm waiting for the test to be all green before pushing the v1.3.0!

All 58 comments

UPDATE new Async Scrolling will be available with [email protected] (Thanks to @homerjam . vuejs/vue-router#1758)

Excellent, does anyone have a good way to hook this up with the router transition object to detect when to scroll? Or should we be using a timeout like in the documentation's example.

@pi0 is there's a hope that it will fix ScrollToTop page transitions?

@typewriter-software check out updated example here https://github.com/vuejs/vue-router/pull/1804 we still need a small modification to vue-router for this to work (I wish I had included this in my last PR!).

Any changes? How to use this promise?

@iamdubx still waiting for the PR referenced above to be released, then I can make an example. For now you should be able to get it to work by installing vue-router from github and using the afterLeave hook as in the example in the PR (the afterLeave hook goes in nuxt.config.js).

@homerjam good to hear, that it's not only me concern this issue.
Meanwhile, I found this awesome project, and wonder, how it fix Scroll behavior? I can't find anything regarding this issue in source code - https://github.com/krestaino/nuepress
Any ideas how it was done?

It looks to me like it's using the default scroll behaviour but the transitions are so quick you don't see any issues.

@iamdubx Thanks! I've been eyeing this issue for some time now, once this issue is resolved in Nuxt I'll update NuePress with the fix.

@homerjam I am suffering from this scroll issue actually. It just appears sporadically as far as I've noticed.

I also can't wait for this fix. Scrollbehavior doesn't work at all for us, even scrollBehavior function is not being called at all. I am using spa config with hash router mode.

I don't want to start a new thread so going to pop it in here, does this include an issue of pages not scrolling to the top and just snapping there? I seem to have that issue on nuxt examples and a clean install in all browsers i try.

@dan-gamble Is this relevant at all to your issue?

https://nuxtjs.org/api/pages-scrolltotop/

That seems to break my page weirdly enough, it also still snaps to the top for some reason.

Found out i needed:

    watchQuery: ['page'],
    key: (to) => to.fullPath,

To get me working again, scrollToTop still snaps up for me though. I'll get a video to show what i get.

Edit
video

Is there any status update on all this? Vue, Nuxt, etc are absolutely fantastic, but the bizarre scrolling to top before route transitions makes the ecosystem pretty much unusable for us. Most of our pages are image-intensive, with large images at the top of each page. With that sort of UI, the scrolling to top before every transition is very noticeable (with or without transition animation) and makes for a terrible user experience. I'm happy to start digging into the source code to try to figure out a workaround, but many others have already tried and it sounds like this is already an area of focus for the core contributors so I'd likely be wasting my time. Unfortunately we're at (or well past) the point where my team needs to make a final decision on React vs. Vue, and this is a critical issue so any status update would be greatly appreciated!

I made head way with it but paused waiting for a PR on vue-router which has
now been merged. I'll try to make an example, but fairly sure it's
resolvable with a custom scrollbehavior function and a transition
event/hook.

On 18 Jan 2018 21:34, "John Kole" notifications@github.com wrote:

Is there any status update on all this? Vue, Nuxt, etc are absolutely
fantastic, but the bizarre scrolling to top before route transitions makes
the ecosystem pretty much unusable for us. Most of our pages are
image-intensive, with large images at the top of each page. With that sort
of UI, the scrolling to top before every transition is very noticeable
(with or without transition animation) and makes for a terrible user
experience. I'm happy to start digging into the source code to try to
figure out a workaround, but many others have already tried and it sounds
like this is already an area of focus for the core contributors so I'd
likely be wasting my time. Unfortunately we're at (or well past) the point
where my team needs to make a final decision on React vs. Vue, and this is
a critical issue so any status update would be greatly appreciated!

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nuxt/nuxt.js/issues/1376#issuecomment-358788870, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABAcGR31wbbnldHa48WqoW6oPnPNjnwrks5tL7jTgaJpZM4O2xp3
.

@homerjam an example would be awesome -- I'm just wrapping up my nuxt project and would really like to get this resolved before launch.

No probs - I also need it for a project I'm working on. If you wouldn't
mind clarifying exactly what behaviour you're hoping for that'd be useful,
eg when it should scroll/remember position/reset etc.

On 18 Jan 2018 22:05, "Matt Crider" notifications@github.com wrote:

@homerjam https://github.com/homerjam an example would be awesome --
I'm just wrapping up my nuxt project and would really like to get this
resolved before launch.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nuxt/nuxt.js/issues/1376#issuecomment-358797244, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABAcGcYVcFvnu14K0WE61YCuPgJSXomlks5tL8A0gaJpZM4O2xp3
.

@homerjam An example would be incredibly helpful. For my specific use case, the scroll position does not return to where it was when navigating back. You can see a minimal repo example on this issue.

https://github.com/nuxt/nuxt.js/issues/1182

@krestaino I think your issue is different than what is discussed here (but probably related).

I think the behavior people here are seeing (and don't want) is:

  • User is scrolled down on Page A
  • User clicks on link to Page B
  • Page A scrolls to the top before loading Page B

The router should behave like a normal website, where clicking a link does not scroll to the top of the page.

I created an example but it requires an as yet unreleased version of vue-router.

@homerjam thanks, I added in your changes to nuxt.config.js and updated vue-router, and that fixes some things but seems to create problems elsewhere (e.g. certain links load in the previous page's scroll position and the back button is pretty borked) :\ I'll try to get to the bottom of this tomorrow..

It was a little rushed I'm afraid! The example has just been merged so
maybe you could use that as a basis to work on it. I'll take another look
when I can too.

On 19 Jan 2018 02:48, "Matt Crider" notifications@github.com wrote:

@homerjam https://github.com/homerjam thanks, I added in your changes
to nuxt.config.js and updated vue-router, and that fixes some things but
seems to create problems elsewhere (e.g. certain links load in the previous
page's scroll position and the back button is pretty borked) :\ I'll try to
get to the bottom of this tomorrow..

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nuxt/nuxt.js/issues/1376#issuecomment-358851192, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABAcGZs75etnK4Nc3Szdw9_5jGYjAQtTks5tMAKIgaJpZM4O2xp3
.

@mcrider check out #2642 - I realised that installing vue-router from github didn't work as the patch it needs isn't included in the dist folder (so the example now uses my fork). I think the logic should now cover most uses cases as expected too.

@homerjam thanks very much for the work on this. Will check it out today. In the meantime, I found that for our purposes, the simple act of setting history.scrollRestoration = 'manual' works like a charm, preserving scroll position on back and forward buttons, while eliminating the painful scroll to top before route changes. Note that we're not using any transition animations on our pages, and we just started exploring this avenue, so it may not be a good solution...but seems worth exploring...

@homerjam Thank you so much! That fixed my issue.

@jkole I'd forgotten about history.scrollRestoration = 'manual' - seems it's pretty widely supported now. It might be something Nuxt could set by default @Atinux @pi0 ?

What does it do exactly @homerjam ?

Tells the browser not to do anything to scroll position on pushstate/popstate. I didn't realize it, but apparently browsers approach the timing of scroll repositioning on page changes differently (some do before/some after popstate)... Will dig out a reference.

There's a good explanation here. Basically would allow us to take total control of scroll position, currently there is still a clash between the browsers behavior and the use of savedPosition - specifically when using the back button.

Hey hey I think we're good here! You rock @homerjam :)

I did add window.history.scrollRestoration = 'manual' to the nuxt.config.js::scrollBehavior method, otherwise when hitting the back button the originating page would jump down before transitioning.

One slight problem, I have a subpage (like your /about/contact, except its dynamic, e.g. /work/_project.vue) where I have scrollToTop set. Doesn't seem to do anything :( When I navigate from the parent (work) page to the child (project) page it loads the child at the scroll position you left the parent. Is else if (to.matched.some((r) => r.components.default.options.scrollToTop)) valid for a dynamic subpage? I'm having trouble trying to debug this config file so I can inspect variables, so not sure if this is correct.

Hmm. Easiest way to find out would probably be to console.log the to state and have a look in there. Could you post a minimal example or tweak one of the ones on the docs site - I think they use glitch?

Yup just realized after my last comment that console.log outputs to the browser not the terminal. The behavior is pretty inconsistent, I'll try to repro using your example.

I think I just had a weird setup with my nested routes. All good now, thanks again!

I just implemented the new scrollBehavior with window.history.scrollRestoration, and it works like a charm, thank you everyone to your big help on this difficult issue, big thank you to @homerjam who made a fix to vue-router!

I'm waiting for the test to be all green before pushing the v1.3.0!

It's like a dream come true, Thank you guys!

@Atinux is it documented? I don't see it yet. How to implement this fix? https://nuxtjs.org/api/configuration-router#scrollBehavior

Is this fully implemented? I'm having a tough time with scroll positions. I think this may be because I'm setting the __nuxt element to position fixed and then scrolling it's overflow. Is there any way to tell nuxt/vue which element is scrolling?

https://glitch.com/edit/#!/brainy-coffee

@chasebank you'll probably need a custom scrollBehavior() function targeting the __nuxt element, you can find the default here - overwrite it in nuxt.config.js.

I am on 1.3.0 and on a nested route ( /journal/_blog/) and it doesn't scroll to top on those if I access the route from the footer of a page, it will keep the same position I clicked from

@Atinux I was trying to use scrollBehaviour on Nuxt 1.4 but it does not persist scroll position on historyBack()

I figured out that the triggerScroll seems to be fired too early, the page/component isn't loaded yet. I solved it for now with a timeout but not sure if thats a good way.

setTimeout(() => {
          resolve(position)
},200)

@dohomi maybe better make a nextTick call?

@daspete I tried but didn't work out so far.

Actually we call the triggerScroll event on the beforeEnter transition hook: lib/app/components/nuxt-child.js#L35

We need more investigation and test on this to be sure it works perfectly. This is dur to the lack of vue-router support on transitions and scroll position :/

Currently working on an app that glitches when two different layouts are used.

Page A and B use layout 1.
Page B and C use layout 2.

From A to B or B to C and vice versa scrolls to the top fine. However if I scroll down page A and navigate to page C for example, the page loads somewhere in the middle.

Resolved for now by using only one layout for all pages, but worth mentioning!

Is it possible for a page to use more than one layout? Could you create an
example of this behaviour?

On Fri, 6 Apr 2018, 21:14 Robin Scholz, notifications@github.com wrote:

Currently working on an app that glitches when two different layouts are
used.

Page A and B use layout 1.
Page B and C use layout 2.

From A to B or B to C and vice versa scrolls to the top fine. However if I
scroll down page A and navigate to page C for example, the page loads
somewhere in the middle.

Resolved for now by using only one layout for all pages, but worth
mentioning!

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/nuxt/nuxt.js/issues/1376#issuecomment-379364645, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABAcGd1wFTignUvyzoc_euU_LOIJ7hDHks5tl8yRgaJpZM4O2xp3
.

After cleaning my dependencies, removing node_modules and installing again the bug is gone. I think it was most likely caused by nuxt not being the latest version (1.4).

I've noticed that the bug persists in Safari in my app. Anyone else have any problems with this?

The pages scroll to the top before switching to the new one. Plus the savedPosition seems to be off when navigating with Safari’s back and forward buttons (only on an image heavy page).

Wrapping resolve(position) in setTimeout fixes the issue somewhat, but the jumps are still noticable.

setTimeout(function() {
  resolve(position)
}, 10)

@Atinux @homerjam Any idea for a workaround for Safari?

@studioscholz could you provide an isolated example of the issue (glitch etc)?

@homerjam

I'll try and provide a repo when I have some time. In the meantime the bug can be observed here: https://www.soccochico.com/catalogue

To toggle it, scroll down the page to one of the very last books and click it. Then navigate back via Safari’s back button. You'll end up somewhere in the middle of the catalogue page. My best guess is that the scrollPosition is resolved before the page has gotten its real height due to the pictures being loaded.

There is also a jump visible when navigating from catalogue to privacy policy for example via the footer.

@studioscholz

It's remembering the scroll position for me which is the desired behaviour! You might want to add a transition to smooth out the catalogue/privacy policy switch...

@homerjam

Weird, the bug is consistent for me with Safari: https://streamable.com/yygsg
I've noticed that if I compute the image height via the mounted hook, it solves the problem. Bit of a nasty workaround though.

@dohomi @Atinux any progress or workarounds on this issue? Also experiencing issues with historyBack(). Have been at this for days and trying to use the setTimeout solution now, but this creates clearly visible jumps on the page, so definitely doesn't look great. Very open to solutions.

@ImreC I still use the workaround with the timeout I showed above. Works fine for me atm

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vadimsg picture vadimsg  Â·  3Comments

nassimbenkirane picture nassimbenkirane  Â·  3Comments

msudgh picture msudgh  Â·  3Comments

pehbehbeh picture pehbehbeh  Â·  3Comments

mattdharmon picture mattdharmon  Â·  3Comments