-
Notifications
You must be signed in to change notification settings - Fork 27.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[NEXT-658] Nextjs 13 Link not scrolling to anchor element #44295
Comments
Can confirm that this is happening on 13.1.1 |
Can use plain old |
i have the same problem |
Same issue here. Neither |
Im facing the same issue. Workaround: currently using the react-scroll lib to scroll between sections in the page. |
I solved this by checking, in a component with an id that might be scrolled to, whether it could find an element with the id set in window.location.hash. If so, scroll to it. I created the below hook to make it easier to use. PS: The first component that uses the hook and finds the element, will handle the scroll. I tried to target the specific current element with a ref callback, but it did not scroll every time (have no idea why, see suggestion below). Hook that always works: import { useEffect, useContext } from "react";
import { NavbarContext } from "@context/NavbarContext";
const useSmoothScrollTo = (targetHash = null) => {
const { navRect } = useContext(NavbarContext);
useEffect(() => {
if (typeof window === "undefined") return;
const hash = targetHash || window.location.hash;
if (!hash) return;
const headerOffset = navRect?.height || "70";
// Only proceed if target is a single hash tag
const startWithHashRegex = /^#\w+/g;
if (!startWithHashRegex.test(hash)) return;
let target = document.querySelectorAll(`${hash}`)[0];
if (!target) return;
const elementPosition = target.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
});
}, [navRect.height, targetHash]);
};
export default useSmoothScrollTo; Callback ref hook that only scrolls now and then: import { useContext, useCallback } from "react";
import { NavbarContext } from "@context/NavbarContext";
const useSmoothScrollTo = (hash = null) => {
const { navRect } = useContext(NavbarContext);
const ref = useCallback(
(node) => {
if (node !== null) {
// Runs on mount of node
if (typeof window === "undefined") return;
const targetHash = hash || window.location.hash;
if (!targetHash) return;
// Only proceed if target is a single hash tag
const startWithHashRegex = /^#\w+/g;
if (!startWithHashRegex.test(targetHash)) return;
const targetHashId = targetHash.substring(1);
const headerOffset = navRect?.height || "70";
const currentNodeId = node.id;
if (targetHashId !== currentNodeId) return;
const elementPosition = node.getBoundingClientRect().top;
const offsetPosition =
elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
});
} else {
// Runs on unmount of node
}
},
[navRect.height, hash]
);
return ref;
};
export default useSmoothScrollTo; |
Another strange behavior which I am noticing in nextjs v13.2 with experimantal |
Next 13.2.1 the same trouble with the anchor link |
Facing this same issue in Next 13.2.3
@myl7 That will come with the window scroll-to-top problem, which has to be resolved on its own. @magnusriga The issue isn't that we cannot write an useEffect to handle this. The issue is: "Really, that's how we are gonna do things?" so although calculating the offSet and manually scrolling may work, that's not the route we want to take at all. Not optimal. The earlier docs had a section showing an example with hash links and disabling scroll to top with as seen HERE
The current docs don't even mention it. |
URL hash (#) handling is in the Routing roadmap (https://beta.nextjs.org/docs/app-directory-roadmap), so we just need to wait for it to arrive. |
Adds support for scrolling based on the [hash fragment](https://en.wikipedia.org/wiki/URI_fragment) in client-side navigations for the App Router, mirroring browser behavior. - `#main-content` → scrolls to `id="main-content"` or `name="main-content"` property - `#top` → scrolls to the top of the page, this is a special case in browsers. - no hash → default scroll behavior, layout that changed Fixes NEXT-658 <!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change(s) that you're making: ## For Contributors ### Improving Documentation or adding/fixing Examples - The "examples guidelines" are followed from our contributing doc https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md - Make sure the linting passes by running `pnpm build && pnpm lint`. See https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md ### Fixing a bug - Related issues linked using `fixes #number` - Tests added. See: https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs - Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md ### Adding a feature - Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. (A discussion must be opened, see https://github.com/vercel/next.js/discussions/new?category=ideas) - Related issues/discussions are linked using `fixes #number` - e2e tests added (https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs - Documentation added - Telemetry added. In case of a feature if it's used or not. - Errors have a helpful link attached, see https://github.com/vercel/next.js/blob/canary/contributing.md ## For Maintainers - Minimal description (aim for explaining to someone not on the team to understand the PR) - When linking to a Slack thread, you might want to share details of the conclusion - Link both the Linear (Fixes NEXT-xxx) and the GitHub issues - Add review comments if necessary to explain to the reviewer the logic behind a change ### What? ### Why? ### How? Closes NEXT- Fixes # --> fixes #44295 --------- Co-authored-by: JJ Kasper <jj@jjsweb.site>
Having the same trouble in Next 13.2.4 while using Link getting back to a tag |
I also have the same issue on 13.2.4, it worked before. |
Same issue with 13.3.0 |
Same issue with 13.3.2 when using router.push |
I wanted to point out that linking to hash fragments now work in Next (as of a recent update), however it does not seem it is possible to make it scroll instead of jumping straight to the location. I also couldn't find a built-in way of accounting for the navbar height, so the current implementation by next.js is suboptimal. I have implemented a custom solution using scrollTo, for now, but looking forward to a built-in solution. PS: The final solution would ideally scroll to the element, if opting in, both when on the same page as the target anchor, and when coming from another page. |
Next js perceives the anchor link as a link to the main page. Now I have fixed it as follows, but scrolling the page to the anchor does not work.
|
Here is my solution. First of all, I implemented a hook based on the suggestion of @magnusriga const useScrollToAnchor = (offset: number = 70) => {
return (targetAnchor: string) => {
console.log('Вызван хук');
if (!(typeof window === 'undefined')) {
const hash = targetAnchor;
const startWithHashRegex = /^#\w+/g;
const targetElement = document?.querySelector(`${hash}`);
if (!startWithHashRegex.test(hash) || !targetElement) {
return;
}
const elementPosition = targetElement.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - offset;
const scroll = () => {
window.scrollTo({
top: offsetPosition,
behavior: 'smooth',
});
};
requestAnimationFrame(scroll);
}
};
};
export default useScrollToAnchor; Next, I use this hook in the component. I replaced the links to the buttons, because the idea allows it. import useScrollToAnchor from '@hooks/useScrollToAnchor';
function Component() {
const scrollToAnchor = useScrollToAnchor(42);
const makeActive = (link: string) => {
scrollToAnchor(link);
};
return (
<button onClick={() => makeActive(link)} onKeyDown={() => makeActive(link)}>
{title}
</button>
)
} In my solution, I am disconnected from the window object or the routing of the application, respectively, it is guaranteed to work. I hope it will help someone. |
Next 13.4.2 using app directory. I have a Works as expected with native |
I still face the issue as well - it links to the main page instead of the anchor element. You can try it live here: https://web3xplorer.com/ |
Same issue here. |
Having the same issue but only to the published app on Azure. On my local dev environment, it works as expected. |
Having the same issue, but is funny, sometimes it works. |
Same issue in NextJS v13.4.1. Using the default anchor as a temporary solution. |
I have the same problem. With a component, I'm trying to direct the user to "/anotherpage#dynamicanchor" from home page ("/") and it does so with a really strange offset. The temporary fix that works for me is using a traditional anchor HTML element but it obviously makes the page reloads, which is not ideal. |
Just to confirm. Is there seriously still not a functional way to build anchor links to elements on the same page in a supposedly "stable" release of nextJs? The only workaround I can find using the Link element is to pass in the full URL by obtaining the current pathname from usePathName() and appending the anchor link. Surely there is a better way? |
The fix I talked about (using an HTML anchor element) works in dev environment but not in production. Any idea why? |
I found a weird fix I guess. Btw I still have the problem in the latest version on Next.js... So I put on the container which holds all my components in the page.tsx in the app dir overflow-y: auto; .. Apparently this css property makes Link not scrolling. If i comment out this line it works after.. I tried to play with it to see what breaks it but I still couldnt find a solution. Maybe someone else find one |
I am having the same issue. In dev on my local server, scroll to hash-id works. However, once deployed on Netlify it does not work. If I inspect the 'Link' tags ('a' tags) I can click the /#id and it will take me to the correct section of my page. Also, I cannot seem to get smooth-scrolling to work even on my local server, it just jumps to the /#id. I hope we can find a fix for all this. |
can confirm that these issues are present on:
|
I had the same problem. |
Does it automatically smooth scroll to fragments (hash ids)? Both when coming from another page and for in-page links? |
Yes it scrolls smoothly to the section fragment when you come from another page. ( It is important to set the following for html {
--scroll-behavior: smooth !important;
scroll-behavior: smooth !important;
} |
@timneutkens can you please reopen this issue? a fix is still not available... |
my fix works in prod:
|
I can confirm the same problems arise for me where locally the anchor links work as expected, but when deployed on netlify, it strips the anchor tag from the URL and reloads hte page:
It would be great to have this issue re-opened if the issue on netlify is related to this same source problem. Otherwise, I can fine a new issue. |
Seems like the issue with netlfiy is that Netlify's latest version of "Next.js Runtime" only supports next v13.4.3 still. I think they've only been fixed as of next v13.4.5. https://github.com/netlify/next-runtime/releases/tag/next-v1.4.7 Related for tracking: opennextjs/opennextjs-netlify#2089 |
@YoniChechik if you're talking about |
u'r a life saver! |
This helped! But in my case, I also had to add the prop
|
The problem is still happening on v13.4.10. |
@vdaguenet please open a new issue and include a reproduction. |
I confirm it worked for me on 13.4.6 and it doesn't now when I upgrade to 13.4.10. |
Verify canary release
Provide environment information
Which area(s) of Next.js are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue
no github link
To Reproduce
/
, hash: "home" }}Describe the Bug
Working on a next 13 app using the experimental flag.
Created a header that has 3 next/link elements and the purpose of those 3 links is to set a hash on the URL and scroll to that anchor element.
The issue is that clicking on those links change the URL but does not scroll to the anchor element, but the strange thing is that by manually changing the hash in the URL does in fact trigger that scroll to the anchor element.
Expected Behavior
Links that add hashes to URL should scroll to the anchor element.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
NEXT-658
The text was updated successfully, but these errors were encountered: