React Router v7 has evolved to support modern, declarative, and data-driven routing patterns. This guide condenses the official docs into a 5-minute reference you can use and share.
1. Declarative Routing (with <Routes> + <Route>)
This is the simplest way to get started with React Router using a JSX-based route structure:
Installation
npm install react-router-dom
Setup
import { BrowserRouter, Routes, Route } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}
- Use to declare routes.
- Use to match a path to a component.
- Works well for simple UI-driven navigation.
2. Custom Routers (Data-Driven Style)
For apps with loaders, actions, and error handling, use createRouter (data router):
Create Custom Router
import {
createRouter,
RouterProvider,
createMemoryHistory,
} from "react-router-dom";
const routes = [
{
path: "/",
loader: () => fetch("/api/home"),
action: async ({ request }) => {
const formData = await request.formData();
return handleForm(formData);
},
element: <Home />,
errorElement: <ErrorPage />,
},
];
const router = createRouter({
history: createMemoryHistory(),
routes,
});
<RouterProvider router={router} />
Why use this?
- Full control over history (memory, hash, browser)
- Built for tests, non-browser environments, or advanced logic
- Lets you plug in loaders/actions even in non-SPA contexts
3. Framework-Style Router Setup
This is the recommended modern way to structure large apps, similar to frameworks like Remix:
Installation (Data Router)
npm install react-router-dom
Example Setup
import {
createBrowserRouter,
RouterProvider,
} from "react-router-dom";
import RootLayout from "./routes/RootLayout";
import ErrorPage from "./routes/ErrorPage";
import Home from "./routes/Home";
import Contact from "./routes/Contact";
const router = createBrowserRouter([
{
path: "/",
element: <RootLayout />,
errorElement: <ErrorPage />,
children: [
{ index: true, element: <Home /> },
{ path: "contact", element: <Contact /> },
],
},
]);
<RouterProvider router={router} />;
Key Benefits
- Built-in support for:
- Nested layouts via
- Data fetching with loader
- Actions for forms
- Error boundaries
- Best choice for complex apps or future Remix migrations
Summary
Approach | Description | Best For |
---|---|---|
Declarative JSX | Use <Routes> + <Route>
|
Small apps or UI-focused routes |
Custom Router | Use createRouter + custom history |
Testing, SSR, advanced logic |
Framework Router | Use createBrowserRouter + loaders/actions |
Real-world apps, data routing |
Want to Learn More?
If you found this article useful and want to go even deeper into React Router v7, check out my new book:
More Effective React Router: Learn React Router v7 in Depth
The book covers 125+ practical chapters about:
- Declarative and Data Routing
- Loaders and Actions
- Advanced Navigation Patterns
- Testing, SSR, Accessibility, and more
Kindle Edition on Amazon
Paperback on Amazon
Built for intermediate to advanced React developers.
Top comments (0)