Clicking a Link does't scroll to top on the next page

Steps to Reproduce

  • create a new Plone/Volto project or use demo.plone.org

  • You can use VLT 6.2.0 or 7.3.1 or plain Volto with Pastanaga

  • add 2 long pages (to have a scroll bar appear when displayed)

  • add a link at the end of the first page that redirects to the 2nd page

    • This could be additionally a footer link pointing to a page, allowing to be on every page.
    • You can duplicate one page multiple times very often in the site root to populate a long sitemap. Then you can use the default sitemap link to test.
  • on the page with the link or on any long page with a sitemap link to a long sitemap, scroll down and click on the link

  • notice the scroll position on the 2nd page or sitemap is not at the top.

Context

Safari (macOS 15.7) always scrolls properly to the top.

Chrome or Firefox (macOS 15.7) scroll to a point in mid of the target page randomly: effect absent or there – depending on (guessed) the type of code managing the rendered link and the response in the background by javascript/react.

I cannot figure out a way to debug that behaviour further.

Updated [[20251030]] 11:24 :

  • There are no events in the console to followup.
  • There seems no difference in the markup of the link.
  • If you add links manually to the rendered DOM using Developer Tools, they behave as expected and scroll to top or anchor.

Further reading

The linked article comment from a different next.js discussion describes some timing effects during buildup of the new page that may affect this result and can lead to some understanding Clicking a Link does't scroll to top on the next page · vercel/next.js · Discussion #64435 · GitHub
The suggested solution to use min-height: 100vh on the body did not help.

History of the discovery

  • Discovered with VLT 6.0.0a21 and Plone 6.1.1 and Volto 18.14.0
  • Present in the current Plone 6.1.3 and Volto 18.28.2 and VLT 7.3.1
  • Same with https://demo.plone.org Plone 6.1.3 and Volto 18.27.3. and VLT 7.2.0

Checking origins of the effect

Sticky header

I was estimating some custom CSS tweaks like using a sticky header could have created this behviour, but after some tests it seems a general issue.

The effect does not show up that much when not having a sticky header, because you always have to scroll to the top to reach the menu. With a sticky header the menu is reachable at every scroll position.

Links inline in the content

Links inside of the content have similar effects.

One exception is using the volto-button-block button, which gives constant proper scroll to top results.

Related

Maybe this is also related to the scroll to anchor navigation issues. Make "scroll to anchor navigation" work in long Volto pages from the navigation (Fat-)menu (or sticky menu)

  • When a link object is clicked in the navigation in anonymous view the issue is present and a page opens somewhere in the middle or at the end (IMPORTANT: if you have no sticky header + navigation, you cannot click the navigation when scrolled to the middle or end of a page)
  • When authenticated and first landing in the link object and then cllicking the link there, opening the page at the top works.

I updated the topic above with more precise version informations.

Related

Scroll history and UX expectations are mentioned in this document on https://html.spec.whatwg.org:

  • 7.2.5 The History interface -> see last Example at the end of subchapter:

    Most applications want to use the same scroll restoration mode value for all of their history entries. To achieve this they can set the scrollRestoration attribute as soon as possible (e.g., in the first script element in the document's head element) to ensure that any entry added to the history session gets the desired scroll restoration mode.

    <head>
      <script>
           if ('scrollRestoration' in history)
                history.scrollRestoration = 'manual';
      </script>
    </head>
    
  • the linked part 7.4.1.1 Session history entries #scroll restoration mode

    A scroll restoration mode indicates whether the user agent should restore the persisted scroll position (if any) when traversing to an entry. A scroll restoration mode is one of the following:

    "auto" – The user agent is responsible for restoring the scroll position upon navigation.

    "manual" – The page is responsible for restoring the scroll position and the user agent does not attempt to do so automatically