DEV Community

Daniel Gruner
Daniel Gruner

Posted on

32

Scroll to anchor element with React Router V6 (hash links, anchor links)

Hi! With inspiration of Nick Coughlin, I developed a pretty simple solution for using hash links or anchor links with React Router V6. As Nick proposes, it's without any further dependency like the popular react-router-hash-links.

Target

Goal is that your app scrolls to a certain element with a certain ID, when a so called hash link or anchor link is used.

Example:

...
// react-router Link component
<Link to="/mypage#myheadline">Press Link to get to headline</Link>
...
Enter fullscreen mode Exit fullscreen mode

By clicking this link, the user expects to be navigated to "/mypage" and scrolled to the element with ID "myheadline"

...
// headline with ID "myheadline"
<h2 id="myheadline">My Headline</h2>
...
Enter fullscreen mode Exit fullscreen mode

ScrollToAnchor.tsx or jsx

Put this component anywhere within your router component. It simply listens for location changes and determines if there is a hash (or element ID) that your app should scroll to.

import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';

function ScrollToAnchor() {
  const location = useLocation();
  const lastHash = useRef('');

  // listen to location change using useEffect with location as dependency
  // https://jasonwatmore.com/react-router-v6-listen-to-location-route-change-without-history-listen
  useEffect(() => {
    if (location.hash) {
      lastHash.current = location.hash.slice(1); // safe hash for further use after navigation
    }

    if (lastHash.current && document.getElementById(lastHash.current)) {
      setTimeout(() => {
        document
          .getElementById(lastHash.current)
          ?.scrollIntoView({ behavior: 'smooth', block: 'start' });
        lastHash.current = '';
      }, 100);
    }
  }, [location]);

  return null;
}

export default ScrollToAnchor;
Enter fullscreen mode Exit fullscreen mode

AWS Q Developer image

Your AI Code Assistant

Generate and update README files, create data-flow diagrams, and keep your project fully documented. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (5)

Collapse
 
ncoughlin profile image
Nick Coughlin

This component has been converted to an NPM package with the following improvements:

  • no longer requires react-router as a dependency
  • typescript compatible

You can view the github repo here:
github > ncoughlin/scroll-to-hash-element

and the NPM repo here:
npm > scroll-to-hash-element

Collapse
 
davidd344 profile image
David Freitas • Edited

if you want scroll for after navbar, it's work for me:


import { useEffect, useRef } from 'react'
import { useLocation } from 'react-router-dom'

function ScrollToAnchor (): null {
  const location = useLocation()
  const lastHash = useRef('')
  const navbarHeight = 110
  console.log(location, lastHash)
  useEffect(() => {
    if (location.hash.length > 0) {
      lastHash.current = location.hash.slice(1)
    }

    if ((lastHash.current.length > 0) && (document.getElementById(lastHash.current) != null)) {
      setTimeout(() => {
        //  s
        const element = document
          .getElementById(lastHash.current)
        // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
        if (element) {
          const elementPosition = element.getBoundingClientRect().top + window.scrollY
          window.scrollTo({
            top: elementPosition - navbarHeight,
            behavior: 'smooth'
          })
        }
        // s
      }, 100)
    }
  }, [location])

  return null
}

export default ScrollToAnchor
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ktechgau profile image
Karla

Hello and thank you for this! Pardon my ignorance I am new to React JS, I have created a component, imported the function to the page I want to use it, but still not working, what am I missing please?

Collapse
 
squeasy profile image
Abdullah Malik

Any chance you still need help with this?

Collapse
 
fadelyang profile image
Fadela Numah Kadenz

It's simple and works, Thankyou

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay