React 19 is still built around the idea of a Single Page Application (SPA): the page never reloads, only the UI changes based on the URL. For routing, we use the react-router-dom package.
Table of Contents
The modern version of React Router (v6+) uses:
<BrowserRouter><Routes><Route element={...}><Link>/<NavLink>- Hooks:
useParams,useNavigate,useSearchParams
Below is the updated approach.
1. Install and Setup
Step 1: Create a React project
npx create-react-app my-app
Step 2: Install React Router DOM
npm install react-router-dom
2. Create Your Pages
In src/data/products.ts
import type { ProductType } from "@/types/Product";
export const products: ProductType[] = [
{
id: "1",
title: "Blue T-Shirt",
price: 19.99,
description: "A comfortable blue t-shirt.",
},
{
id: "2",
title: "Red Hoodie",
price: 49.99,
description: "Warm and cozy hoodie.",
},
{
id: "3",
title: "Sneakers",
price: 79.99,
description: "Stylish everyday sneakers.",
},
];
src/pages/Products.jsx
import { products } from "@/data/Products";
import { Link } from "react-router-dom";
export default function Products() {
return (
<div>
<h2 className="text-2xl font-bold mb-4">Products</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{products.map((p) => (
<div key={p.id} className="bg-white p-4 rounded shadow-sm">
<h3 className="font-semibold">{p.title}</h3>
<p className="text-sm text-gray-500">{p.description}</p>
<div className="mt-2 flex items-center justify-between">
<div className="font-bold">${p.price}</div>
<Link to={`/products/${p.id}`} className="text-sm underline">
View
</Link>
</div>
</div>
))}
</div>
</div>
);
}
src/pages/Carts.jsx
function CartPage() {
return (
<div>
<h1>Cart page</h1>
</div>
);
}
export default CartPage;
3. Configure Routing (React 19 Compatible)
Do the same for the contact page.
Configure react routing in App.tsx file
In the App.js component, we configure routing for different components, we are setting the home page, about, and contact page with different URLs.
import { Routes, Route } from "react-router-dom";
import MainLayout from "./layouts/MainLayout";
import Home from "./pages/Home";
import Products from "./pages/Products";
import Product from "./pages/Product";
import Cart from "./pages/Cart";
import NotFound from "./pages/NotFound";
export default function App() {
return (
<Routes>
<Route path="/" element={<MainLayout />}>
<Route index element={<Home />} />
<Route path="products" element={<Products />} />
<Route path="products/:id" element={<Product />} />
<Route path="cart" element={<Cart />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
);
}
In layout for src/layouts/MainLayout.tsx file we had
import { Outlet } from "react-router-dom";
import NavBar from "../components/NavBar";
export default function MainLayout() {
return (
<div className="min-h-screen bg-gray-50">
<NavBar />
<main className="container mx-auto p-4">
<Outlet />
</main>
</div>
);
}
4. Create Navigation or header component
We have successfully configured routing, let’s create a Navigation component inside the src/components/Navbar.tsx folder. Let’s create Navigation.jsx and add the following react-router Link component to the link URL.
import { NavLink } from "react-router-dom";
import { Button } from "./ui/button";
export default function NavBar() {
return (
<header className="bg-white shadow-sm">
<div className="container mx-auto flex items-center justify-between p-4">
<h1 className="text-lg font-bold">My Shop</h1>
<nav className="flex items-center gap-3">
<NavLink
to="/"
end
className={({ isActive }) =>
isActive ? "text-blue-600 font-semibold" : ""
}
>
Home
</NavLink>
<NavLink
to="/products"
className={({ isActive }) =>
isActive ? "text-blue-600 font-semibold" : ""
}
>
Products
</NavLink>
<Button asChild>
<NavLink to="/cart">Cart</NavLink>
</Button>
</nav>
</div>
</header>
);
}
✔ Modern React Router uses a function:
className={({ isActive }) => (isActive ? "active" : "")}
5. Dynamic Routes (params)
Add dynamic routes:
<Route path="/products" element={<BooksPage />} />
<Route path="/products/:id" element={<BookPage />} />
Get params inside component:
import { useParams } from "react-router-dom";
const ProductPage = () => {
const { id } = useParams();
return <h2>Book ID: {id}</h2>;
};
6. Query Params
import { useSearchParams } from "react-router-dom";
const MyPage = () => {
const [params] = useSearchParams();
const sort = params.get("sort"); // ?sort=name
};
7. Redirect (Updated for v6)
Option 1: Component redirect
import { Navigate } from "react-router-dom";
return <Navigate to="/notfound" />;
Option 2: Navigating in code
const navigate = useNavigate();
navigate("/about");
8. Nested Routes (React 19 same as v6)
In App.tsx:
<Route path="/products/*" element={<Products />} />
Inside Products.jsx:
<Routes>
<Route path="clothes" element={<Clothes />} />
</Routes>
URL:
/products/clothes
9. Back Button
const navigate = useNavigate();
<button onClick={() => navigate(-1)}>Back</button>
10. 404 Page (Updated)
App.js:
<Route path="/notfound" element={<NotFound />} />
<Route path="*" element={<NotFound />} />
✔ Summary: Using Routing in React 19
Routing in React 19 is still done exactly the same way as React 18:
- Install
react-router-dom - Wrap app in
<BrowserRouter> - Use
<Routes>+<Route> - Use
<NavLink>for active styling - Use hooks for params, query, navigation