DEV Community

James Uyi
James Uyi

Posted on

3

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.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (1)

Collapse
 
ogemanuel profile image
Ogunmola Emmanuel Iyanuoluwa

Great insight James, well done 👍🏿

Cloudinary image

Optimize, customize, deliver, manage and analyze your images.

Remove background in all your web images at the same time, use outpainting to expand images with matching content, remove objects via open-set object detection and fill, recolor, crop, resize... Discover these and hundreds more ways to manage your web images and videos on a scale.

Learn more