DEV Community

ScrolltoTop with React and react-router v6.

Navigating to the top of the page on a multi-page website using React and react-router v6

I have done a multi-page project with react with navigation in the header and footer. While the navigation on the header is not a real challenge, the footer navigation needs some extra coding for it to work perfectly or at least better.

Footer Navigation - the challenge

You have been following this website from the top and now you have reached the bottom of the site and at the bottom, there is some navigation to other pages. Clicking on any of the links works, the navigation is moving to the required page. But hold on, I am a keyboard user for one reason or the other. The page has moved to the right page but pressing the tab key again you see that you have been redirected to the bottom of the new page - yes that's a bit frustrating and confusing to assistive technology users.

The Fix

Create a ScrollToTop function in the App.js file

import { useEffect } from 'react';
import {  Routes, Route , useLocation } from 'react-router-dom'
import Header from './pages/shared/Header';
import Footer from './pages/shared/Footer';
import Features from './pages/features/Features';
import Pricing from './pages/pricing/Pricing';
import Stories from './pages/stories/Stories';
import Home from './pages/home/Home';
import { DataProvider } from './pages/context/Context';
import './sass/App.scss';

function App() {

  const ScrollToTop = () => {
    const { pathname } = useLocation();
    console.log(pathname)
    useEffect(() => {
      window.scrollTo(0, 0);
    }, [pathname]);

    return null;
  }

  return (
    <div className="App">
      <Header />

      <DataProvider>

          <ScrollToTop />
          <Routes>

            <Route path="/" element={<Home />} />
            <Route path="stories" element={<Stories />} />
            <Route path="features" element={<Features />} />
            <Route path="pricing" element={<Pricing />} />

          </Routes>

        <Footer />
      </DataProvider>

    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

At this point, if you try the navigation, the focus will still stay at the bottom. I had assumed that I had done everything possible. A few more steps to solve this issue.

Move to the top of the file that has to be at the top and locate the element that should have focus when the page is navigated to. On this element write a tabindex=-1.

A negative value (usually tabindex="-1") means that the element is not reachable via sequential keyboard navigation, but could be focused with JavaScript or visually by clicking with the mouse. A negative value is useful when you have off-screen content that appears on a specific event. The user won't be able to focus any element with a negative tabindex using the keyboard, but a script can do so by calling the focus() method. (source - MDN)

import useRef in the same file
import { useContext, useRef , useEffect} from 'react'

and include the following in the component

const homeMain = useRef()

    useEffect(() => {
        homeMain.current.focus()
    })
Enter fullscreen mode Exit fullscreen mode

On the element with the tabindex add the ref attribute <main tabIndex="-1" ref={homeMain} >. Do this to all the pages .

Here is a GitHub link to the project Photosnap website - a challenge project by Frontend Mentor. The link for the live preview

For a list of Frontend Mentor challenge projects Frontend Mentor Challenge projects

Top comments (0)