DEV Community

James Uyi
James Uyi

Posted on

How to Fix React Router's Scroll Position on Page Transitions

When working on a React project recently, I noticed an odd behavior: whenever I navigated from one page to another using the navigation bar, the new page wouldn't start from the top. If I was on the footer section or anywhere below the navbar, the transition seemed abrupt, as if there was no smooth scrolling to the top of the new page.
The quick fix for this issue is to create a root layout if you don't have one already, and then make all other routes children of that layout element. Let's dive into the code.
Initially, my router configuration looked like this:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
  },
  {
    path: "/about",
    element: <About />,
    errorElement: <ErrorPage />,
  },
  {
    path: "/contact us",
    element: <Contact />,
    errorElement: <ErrorPage />,
  },
]);
Enter fullscreen mode Exit fullscreen mode

To resolve the scrolling issue, the first step is to create a layout component (e.g., layout.tsx or layout.jsx):

import { Outlet, useLocation } from "react-router-dom";
import { useLayoutEffect } from "react";

const Layout = () => {
  const location = useLocation();

  useLayoutEffect(() => {
    document.documentElement.scrollTo({ top: 0, left: 0, behavior: "instant" });
  }, [location.pathname]);

  return (
    <div>
{/* you could render your navbar  component here */}
      <Outlet />
{/* you could render your  footer component here */}
    </div>
  );
};

export default Layout;

Enter fullscreen mode Exit fullscreen mode

Note: It's recommended to render your navbar and footer components within this layout instead of repeating them on every component.

Next, in your main entry point (e.g., main.tsx or wherever you have your router configuration), import the layout and use it as follows:

const router = createBrowserRouter([
  {
    path: "/",
    element: <Layout />,
    children: [
      {
        path: "/",
        element: <Root />,
        errorElement: <ErrorPage />,
      },
      {
        path: "/about",
        element: <About />,
        errorElement: <ErrorPage />,
      },
      // Add other routes here
    ],
  },
]);
Enter fullscreen mode Exit fullscreen mode

With this configuration, whenever you navigate from one page to another, the new page should always start from the top, providing a smooth scrolling experience.

Top comments (1)

Collapse
 
ogemanuel profile image
Ogunmola Emmanuel Iyanuoluwa

Great insight James, well done 👍🏿