Why I Stopped Using Next.js Navigation
Next.js has been my go-to framework for building full-stack apps for years. Built-in API routes, image optimization, and good integrations, there are a lot of reasons to use it. But there's one part I'm not a fan of...
and that's page navigation.
Navigations in the app router have always felt slow to me. So I've been experimenting with different ways to get instant page navigation speed. The result is the fastest Next.js app I've probably ever built.
๐ Our navigation speed after this article
Here's an overview of the architecture:

1. Install React Router
Opting out of Next.js's default navigation is surprisingly easy with react-router (formerly part of Remix):
npm i react-router
2. Create a Static App Shell
This page is a simple wrapper that dynamically loads the frontend app we will create.
"use client";
import dynamic from "next/dynamic";
// ๐ we'll create this in step 4
const App = dynamic(() => import("@/frontend/app"), { ssr: false });
export default function Home() {
return <App />;
}
3. Update Next.js Config
In our next.config.js
, we rewrite all non-API routes to our static app shell:
/** @type {import('next').NextConfig} */
const nextConfig = {
rewrites: async () => {
return [
{
// ๐ matches all routes except /api
source: "/((?!api/).*)",
destination: "/static-app-shell",
},
];
},
};
export default nextConfig;
4. Define Routes With React Router
Let's define the app we import in our static shell. We'll create it in a folder different from our main app, for example, '/frontend`. Here, we use react-router navigation to create pages and which components they render.
import { BrowserRouter, NavLink, Route, Routes } from "react-router";
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/page-one" element={<p>page one</p>} />
<Route path="/page-two" element={<p>page two</p>} />
</Routes>
</BrowserRouter>
);
}
That's it - we now have full client-side routing in Next.js! ๐
All components we now create in our /frontend
folder are automatically client components, so we need no more use client
. Remember to use react-router's <NavLink />
instead of NextJS <Link />
for navigation.
Cheers for reading! If you have any feedback or would like to be a guest author on Upstash, reach out at josh@upstash.com
๐