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 />,
},
]);
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;
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
],
},
]);
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)
Great insight James, well done 👍🏿