Closed alexvcasillas closed 1 year ago
Same for me... How to fix that?
I think it scrolls up to the nearest <div data-nextjs-scroll-focus-boundary />
, this div is automatically created when you wrap your page in a layout. It is supposed to assure scroll restoration within layouts.
you can see in the video below :
@ Fredkiss3 Thanks for your answer :) Yes you are right, but what if I don't want to? Normally I want it to just scroll all the way to the top when clicking on another page. That should be clarified.
I don't know, they added this feature because it seemed really nice (that's what I know, but maybe I'm wrong), but it seems like it requires the creation of a new react API to do so. What I would have liked from them is that they don't include the scroll restore functionality before it is implemented by react.
(sorry for my broken english)
I thought this scrolling behavior was a bug at first and rolled back to the pages directory because of it.
Scrolling to top after clicking a link seems like it should be the default behavior to match "web" expectations and maybe you should have to opt into this scroll to nearest layout container div behavior if that's what you want?
Or maybe rather than scrolling to the top of layouts inner content, it should scroll to the top of the layout itself to give context to the page navigation? So ie if you are just using a root layout it would always just scroll to the top of the entire pag. If your nested layout includes tabs it would scroll to show the tabs also.
For now can be fixed by adding a <ScrollUp />
component to your page:
'use client'
import { useEffect } from 'react'
export default function ScrollUp() {
useEffect(() => window.document.scrollingElement?.scrollTo(0, 0), [])
return null
}
I have some routes using the Tailwind UI Sidebar Layout where html
and body
need h-full
. So this wasn't working. more details
So I had to use this on those routes:
'use client';
import { useEffect } from 'react';
export default function ScrollUpBody() {
useEffect(() => document.body?.scrollTo(0, 0), []);
return null;
}
Not fun.
Hey, are you still having the same problem after the latest canary release ? You can install it with next@canary
.
I've seen that they removed the unnecessary divs appearing inside children of layouts in this PR : #43717
I have been curious as well. There is a bug on canary that breaks my app, and maybe all Windows users. issue
For others who come across this issue, I ran into the same thing, but was able to fix it by removing an unnecessary layout. My directory structure looked like:
app/layout.tsx
app/page.tsx
app/blog/[...slug]/layout.tsx
app/blog/[...slug]/page.tsx
In my case, navigating to one of the blog/2020/post-name
pages had the page start half-way down, without scrolling back up to the top. Looking at the DOM structure, there were two layers of <div data-nextjs-scroll-focus-boundary />
elements.
I found that removing my app/blog/[...slug]/layout.tsx
and wrapping my one-off layout into app/blog/[...slug]/page.tsx
instead fixed the issue, since now there was only one layer of layouts rather than two. I moved common layout code into a separate component to share between the two pages where it's needed:
app/layout.tsx
app/page.tsx
app/blog/[...slug]/page.tsx
components/layout.tsx
For a content-based website like the one I was working on, it was a good reminder that nested layouts are probably more meant for apps with truly nested frames rather than a single view. I guess hearing the word "layout" made me think it'd replace my Layout
components 1:1.
Hey, are you still having the same problem after the latest canary release ? You can install it with
next@canary
.I've seen that they removed the unnecessary divs appearing inside children of layouts in this PR : #43717
Hi, I'm using the latest 13.0.7-canary.6
version but I have the same issue
I'm using 13.0.7
and the issue is better, but it still does not scroll all the way up if I want it to. It will scroll right below the header.
Same here. We're trying to add a simple layout with a shared header and the main content. On navigation, the page doesn't scroll to the top and the header is always hidden. We're using 13.0.7
For now can be fixed by adding a
<ScrollUp />
component to your page:'use client' import { useEffect } from 'react' export default function ScrollUp() { useEffect(() => window.document.scrollingElement?.scrollTo(0, 0), []) return null }
Won't this also be triggered when using the back button though?
Confirming the scroll restoration not working after upgrade to NextJS 13.1 just today.
Still doesn't work, nextJS 13.1.1
.
I'm also on 13.1.1, and it doesn't seem like Next.js is adding any elements with data-nextjs-scroll-focus-boundary
.
I actually have a relatively simple website that reproduces this behavior if it helps.
/docs
folder)Running document.querySelectorAll('[data-nextjs-scroll-focus-boundary'])
on a few pages returns empty NodeLists. I also tried things like removing display: flex
from body
to no avail.
The next problem is when you press the browser's back button: Normally the previous HTML page should be displayed in the same scroll position as before. But the page hangs and blocks for a moment, and then the document jumps back to the top of the page. This is very inconvenient when I'm scrolling through a list of, for example, blog posts and then go to the details of a post and then want to go back to look at the next blog post. I find this behavior very annoying.
+1
I'm also on 13.1.1, and it doesn't seem like Next.js is adding any elements with
data-nextjs-scroll-focus-boundary
.I actually have a relatively simple website that reproduces this behavior if it helps.
- Repo: https://github.com/stevenpetryk/mafs (the
/docs
folder)- Live site example page
Running
document.querySelectorAll('[data-nextjs-scroll-focus-boundary'])
on a few pages returns empty NodeLists. I also tried things like removingdisplay: flex
frombody
to no avail.
Hi the div data-nextjs-scroll-focus-boundary
is not longer available... This issue is very annoying and I can't understand why is not on the top priority list.
Maybe it happens only for certain configuration or styles?!
Still doesn't work on NextJs 13.1.2-canary.0
It seems a little better on NextJs 13.0.5
I'm on NextJS 12.2.5
and was also observing this problem on pages with shared layouts, where, when I clicked on a Link on Page A to get to Page B, Page B would load scrolled to the position that Page A was at. (i.e. if I was 50% of the way scrolled down on Page A, Page B would load scrolled 50% of the way down!)
Things I tried that didn't work:
Things that I did to make it work:
scroll-behavior: smooth
from my html
element (and stuck it on the body
). h/t https://stackoverflow.com/a/63379899/4172535 next/link
Link
, I passed scroll={true}
~~That combination seems to have fixed things for my situation.~ Update: I think scroll={true}
doesn't do anything and the real issue is the scroll behavior smooth on the HTML element.
Also wonder to what degree this issue is related: https://github.com/vercel/next.js/issues/40719
With scroll={true}
on next/link
Link
it seems to work better. But sometimes, scrolling stop under my header I don't know why.
What's the intuition behind scroll={true}
helping, given that the docs indicate that's the default?
yeah I don't know why it's working better
What's the intuition behind
scroll={true}
helping, given that the docs indicate that's the default?
That's a good question, @steve-marmalade. I'm going to update my answer to strike-through that bit, because it doesn't do anything.
I just wanted to point out that I do not see a scroll property on the beta docs. It is not in props or legacy props. 🤷
i think problem isn't solved yet. Right?
Same problem
I found the error....Actually it is happening because I set height:100% and overflow: auto on html element.
For what it's worth, this is reproducible on the app playground, which has neither of those.
I found the error....Actually it is happening because I set height:100% and overflow: auto on html element.
I don't have either in my project, but am still facing the issue :(
Still and issue in NextJS 13.1.2, it seems to not scroll at all after navigating using next/link component. Specifically in Server Side components.
why is not on the top priority list.
Scroll behavior and back navigation are on the list of things to investigate further. E.g. there's this PR: #43845. As of right now it's expected that navigation scrolls to the nearest common layout that changed, this ensures that when you're navigating between tabs it keeps the relevant changed content in view and doesn't start from the top of the page. #43845 changes that behavior to scroll to the top of the page if the element stays in the viewport while at the top of the page. This behavior is relevant because in the new router you can soon create e.g. a tab UI similar to what you can see on https://app-dir.vercel.app/ssg where you wouldn't want it to scroll to top on interactions.
Please be patient while we work through the backlog of all app
related issues, it's in beta for a reason and to reiterate it's not meant to be used in production yet.
Please don't post comments like "same issue", "It's still an issue in version x.x.x", "is this resolved yet" they're not constructive.
While it's getting under further investigation, for the ones who are still facing this unexpected behaviour (although there're some reasons behind this as Tim stated), this workaround is functional and working:
For now can be fixed by adding a
<ScrollUp />
component to your page:'use client' import { useEffect } from 'react' export default function ScrollUp() { useEffect(() => window.document.scrollingElement?.scrollTo(0, 0), []) return null }
Just wanted to remark that you can import this "Scrollup" component into your desired "page.jsx" in the route you expect to navigate and be auto-scrolled to the top of the page instead of remaining at the actual scroll spot.
Thanks Tim for the insights about this topic.
The problem with that workaround is that it'll also be triggered if you use the back button, which is generally not the desired behaviour -- the "native" behaviour is to to restore the previous scroll position.
It's a viable interim solution if you don't mind that though.
The problem with that workaround is that it'll also be triggered if you use the back button, which is generally not the desired behaviour -- the "native" behaviour is to to restore the previous scroll position.
This is a good point. I also wanted to preserve the default behavior of back/forward navigations from the browser UI (or mouse forward/back, swiping gesture at the screen edge, etc) while bringing the scroll to the top for the navigations triggered by my <Link />
.
So I came up with something that works for me, but not really sure if the solution is a right way to approach this or if it's against best practices ¯_(ツ)_/¯.
Anyways, here's the basic idea (in case it's helpful to someone).
<Link />
s and that caused by all the other methods. I mark this in onClick
of my <Link />
s.usePathname
and useEffect
. useEffect
above, check if the path change was triggered by the <Link />
.window.scrollTo({ top: 0 })
otherwise do nothing.Here's some code.
// ./components/MyLayout.tsx
"use client";
import { usePathname } from "next/navigation";
import { useEffect } from "react";
let top0Requested = false;
export function requestTopO() {
top0Requested = true;
}
export default function MyLayout(props) {
const currentPath = usePathname();
useEffect(() => {
let requestId: number | undefined;
if (top0Requested) {
const rAFCallback = () => {
if (window.scrollY !== 0) {
window.scrollTo({ top: 0 });
requestId = requestAnimationFrame(rAFCallback);
} else {
top0Requested = false;
}
};
requestId = requestAnimationFrame(rAFCallback);
}
return () => {
requestId && cancelAnimationFrame(requestId);
};
}, [currentPath]);
return <YourUIComponent {...props} />
}
// ./components/MyNav.tsx
import { requestTopO } from "./MyLayout";
export default function MyNav() {
return (
<ul>
<li>
<Link href="/about" onClick={requestTopO}>
About
</Link>
<Link href="/work" onClick={requestTopO}>
Work
</Link>
<Link href="/contact" onClick={requestTopO}>
Contact
</Link>
</li>
</ul>
);
}
I experience similar behavior, but there is something worth mentioning the behavior is different from a page visit through other pages, vs a direct visit with further navigation within the page. In both scenarios behavior is unexpected.
Visit through the homepage and then navigating between links https://user-images.githubusercontent.com/2697570/213864595-3daf1685-7883-473a-a813-de4661e07f4f.mp4
Page refresh and navigation between links https://user-images.githubusercontent.com/2697570/213864614-70788b56-0bd9-450d-bb96-401be0b78091.mp4
it's in beta for a reason and to reiterate it's not meant to be used in production yet
@timneutkens you're right and I'm sorry: I thought only to solve one of my needs and not for the benefit of the product: thanks for your useful explanation and I'm sure we'll find the best solution to cover all the desired use cases 💪🏻
Sincerely, a Next.js ♥️ lover
We've landed #43845 which changes the heuristic to scroll to top when the element is in the viewport when scroll position is at the top. If it's not in the viewport when at the top of the page it'll scroll to the changed element.
I am trying with version 13.1.6, but personally I am still experiencing problems using a basic layout with fixed navbar to navigate between pages that share the same layout. I don't understand if with https://github.com/vercel/next.js/pull/43845 merged this case should already be covered or it is still a work in progress.
This shouldn't happen. I tried to reproduce it, but I wasn't able to.
Could you try reproducing the issue here https://github.com/JanKaifer/next-repro-42492
It has a navbar with position: fixed
, but it still works as expected.
There could be an issue if the navbar is taller than the viewport, could that be your case? (In that case, it should scroll to the top of the page, just below the navbar).
This shouldn't happen. I tried to reproduce it, but I wasn't able to. Could you try reproducing the issue here https://github.com/JanKaifer/next-repro-42492 It has a navbar with
position: fixed
, but it still works as expected.There could be an issue if the navbar is taller than the viewport, could that be your case? (In that case, it should scroll to the top of the page, just below the navbar).
Thank you for your reply! After an hour of trying, I think the problem is related to CSS Modules. You can try this diff, the content of styles.module.css
is not relevant.
diff --git a/app/[num]/page.tsx b/app/[num]/page.tsx
index 83206f4..a939440 100644
--- a/app/[num]/page.tsx
+++ b/app/[num]/page.tsx
@@ -1,17 +1,13 @@
import Link from "next/link";
+import styles from './styles.module.css'
export default function Page({ params: { num } }) {
return (
<div>
{new Array(100).fill(0).map((_, i) => (
<div
+ className={styles.square}
key={i}
- style={{
- height: 100,
- width: 100,
- background: "pink",
- margin: 10,
- }}
>
<Link href={`/${Number(num) - 1}`}>lower</Link>
<div>{num}</div>
Thank you, I added that to the repro, and I'm able to reproduce this now. Will look into it.
I have added a test with a repro here:
[branch was deleted]
It's a bit tricky because the playwright click()
won't reproduce this. We need to do document.getElementById("...").click()
+1
This affects the back button with both the pages
and app
directories for me and breaks a fundamental part of the browsing experience.
+1
This affects the back button with both the
pages
andapp
directories for me and breaks a fundamental part of the browsing experience.
Hi, using pages
you can add:
experimental: {
scrollRestoration: true,
}
in the experimental
section of your next.config.js
file to support the back button restoration.
For me, the scroll does work but it doesn't scroll all the way up. Seems like it's scrolling to the top, minus the height of the sticky navbar. When I remove the header, it scrolls just as expected. Anyone know a solution to this?
edit: it also works perfectly fine when just reloading the page, with the header/navbar still there.
@chrber04 This sounds like a bug. Could you open a new issue for this, please?
I have the same issue during the development.
This is clear a bug, please keep it open
Verify canary release
Provide environment information
Operating System: Platform: linux Arch: x64 Version: #1 SMP Mon Sep 19 19:14:52 UTC 2022 Binaries: Node: 16.15.0 npm: 8.5.5 Yarn: 3.2.4 pnpm: N/A Relevant packages: next: 13.0.2 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0
What browser are you using? (if relevant)
Chrome 107.0.5304.87
How are you deploying your application? (if relevant)
Vercel
Describe the Bug
When navigating between pages using
Link
, the page does not scroll up by default wich is supposed to be the default behaviour ofnext/link
Expected Behavior
The page scrolls up when switching pages unless I manually disable this feature of
next/link
Link to reproduction
https://beta.otpfy.com/
To Reproduce
auth
page the scroll is preserved and not scrolled to the top\:
From SyncLinear.com | NEXT-378