Anchor links (#) not working within the same page in Next.JS app router

838 Views Asked by At

I have a <Link/> component with the href set to #targetDiv in my Next.js app. Ideally, when a user clicks on the button/link, the page should scroll to the respective section with the id #targetDiv . But it doesn't work that way.

I went through some of the other related posts here, and following the suggestions, I tried replacing the <Link/> component with normal <a></a> tags. But it still doesn't work for me.

In both scenarios, when the user clicks the button/link, the url changes to /about/#targetDiv and not /about#targetDiv . As a result the page scrolls to the top of the page instead

I'm using Next.Js version 13.4.9, with the new /app router. Surprisingly in the official documentation, even though the /pages router mentions it, there is absolutely no mention of this in the official /app router documentation!

There are multiple GitHub issues created discussing the same problem, but either they have a confusing conclusion, where some people are claiming it's working fine for for them, while others claim its not.... or they conclude with building a separate functions/custom solutions to handle anchor links.

Is there really no other way to handle anchor-tags in Next.Js, besides building custom solutions ?

1

There are 1 best solutions below

0
Rijwan Khan On

The issue you are facing with anchor links in Next.js is related to how the framework handles routing. By default, Next.js scrolls to the top of the page when the URL changes. To make anchor links work as expected, you can use the react-scroll library.

Here's how you can implement it:

  1. First, install the react-scroll library:
npm install react-scroll
  1. Import the necessary components from react-scroll in your component file:
import { Link as ScrollLink, animateScroll as scroll } from "react-scroll";
  1. Replace your <Link> component with the ScrollLink component:
<ScrollLink to="targetDiv" smooth={true} duration={500}>
  Click me
</ScrollLink>
  1. Add an id to the section you want to scroll to:
<div id="targetDiv">
  ...
</div>

Now, when the user clicks on the link, it will smoothly scroll to the target section with the id targetDiv. Make sure to adjust the smooth and duration props according to your needs.

Keep in mind that this solution uses a third-party library. If you prefer not to use external dependencies, you would need to implement a custom solution using JavaScript scroll functions.