What is react-router?
The react-router npm package is a declarative routing library for React, allowing you to add navigation functionality to your React applications. It enables you to handle URL routing, match routes to your React components, and manage navigation state in a single-page application (SPA) environment.
What are react-router's main functionalities?
Basic Routing
This code demonstrates how to set up basic routing in a React application using react-router. It includes navigation links and route components that render different components based on the URL path.
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to='/'>Home</Link>
</li>
<li>
<Link to='/about'>About</Link>
</li>
</ul>
</nav>
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
Dynamic Routing
This code snippet shows how to implement dynamic routing with path parameters. The User component will render with the appropriate user ID based on the URL.
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
function App() {
return (
<Router>
<div>
<ul>
<li>
<Link to='/users/1'>User 1</Link>
</li>
<li>
<Link to='/users/2'>User 2</Link>
</li>
</ul>
<Route path='/users/:id' component={User} />
</div>
</Router>
);
}
function User({ match }) {
return <h2>User ID: {match.params.id}</h2>;
}
Nested Routing
Nested routing allows you to create routes within routes. This example shows a Layout component with a nested Dashboard route.
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
function App() {
return (
<Router>
<Route path='/' component={Layout} />
</Router>
);
}
function Layout({ match }) {
return (
<div>
<nav>
<Link to={`${match.url}dashboard`}>Dashboard</Link>
</nav>
<Switch>
<Route path={`${match.path}dashboard`} component={Dashboard} />
</Switch>
</div>
);
}
function Dashboard() {
return <h2>Dashboard</h2>;
}
Protected Routes
Protected routes are used to restrict access to certain parts of your application. This example shows a route that renders a component only if the user is authenticated, otherwise it redirects to a login page.
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
function App() {
return (
<Router>
<Route path='/protected' render={() => (
isAuthenticated() ? (
<ProtectedComponent />
) : (
<Redirect to='/login' />
)
)} />
</Router>
);
}
function isAuthenticated() {
// Authentication logic here
return true;
}
function ProtectedComponent() {
return <h2>Protected</h2>;
}
Other packages similar to react-router
vue-router
Vue-router is the official router for Vue.js. It provides similar functionalities for Vue applications as react-router does for React applications, including nested routes, dynamic segments, and navigation guards. However, it is designed to work seamlessly with Vue's reactivity system.
reach-router
Reach Router is another routing library for React, which aims to be more accessible and simpler to use than react-router. It has a smaller API surface area and focuses on accessibility by managing focus after route transitions. However, as of my knowledge cutoff in 2023, Reach Router has been officially merged with React Router, and its features have been integrated into React Router v6.
react-router
is the primary package in the React Router project.
Installation
npm i react-router
v7.7.0
Date: 2025-07-16
What's Changed
Unstable RSC APIs
We're excited to introduce experimental support for RSC in Data Mode via the following new APIs:
For more information, check out the blog post and the RSC Docs.
Minor Changes
create-react-router
- Add Deno as a supported and detectable package manager. Note that this detection will only work with Deno versions 2.0.5 and above. If you are using an older version version of Deno then you must specify the --package-manager CLI flag set to deno
. (#12327)
@react-router/remix-config-routes-adapter
- Export DefineRouteFunction
type alongside DefineRoutesFunction
(#13945)
Patch Changes
-
react-router
- Handle InvalidCharacterError
when validating cookie signature (#13847)
-
react-router
- Pass a copy of searchParams
to the setSearchParams
callback function to avoid mutations of the internal searchParams
instance (#12784)
- This causes bugs if you mutate the current stateful
searchParams
when a navigation is blocked because the internal instance gets out of sync with useLocation().search
-
react-router
- Support invalid Date
in turbo-stream
v2 fork (#13684)
-
react-router
- In Framework Mode, clear critical CSS in development after initial render (#13872, #13995)
-
react-router
- Strip search parameters from patchRoutesOnNavigation
path
param for fetcher calls (#13911)
-
react-router
- Skip scroll restoration on useRevalidator()
calls because they're not new locations (#13671)
-
react-router
- Support unencoded UTF-8 routes in prerender config with ssr
set to false
(#13699)
-
react-router
- Do not throw if the url hash is not a valid URI component (#13247)
-
react-router
- Remove Content-Length
header from Single Fetch responses (#13902)
-
react-router
- Fix a regression in createRoutesStub
introduced with the middleware feature (#13946)
-
As part of that work we altered the signature to align with the new middleware APIs without making it backwards compatible with the prior AppLoadContext
API
-
This permitted createRoutesStub
to work if you were opting into middleware and the updated context
typings, but broke createRoutesStub
for users not yet opting into middleware
-
We've reverted this change and re-implemented it in such a way that both sets of users can leverage it
-
⚠️ This may be a breaking bug for if you have adopted the unstable Middleware feature and are using createRoutesStub
with the updated API.
// If you have not opted into middleware, the old API should work again
let context: AppLoadContext = {
/*...*/
};
let Stub = createRoutesStub(routes, context);
// If you have opted into middleware, you should now pass an instantiated
// `unstable_routerContextProvider` instead of a `getContext` factory function.
let context = new unstable_RouterContextProvider();
context.set(SomeContext, someValue);
let Stub = createRoutesStub(routes, context);
-
@react-router/dev
- Update vite-node
to ^3.2.2
to support Vite 7 (#13781)
-
@react-router/dev
- Properly handle https
protocol in dev mode (#13746)
-
@react-router/dev
- Fix missing styles when Vite's build.cssCodeSplit
option is disabled (#13943)
-
@react-router/dev
- Allow .mts
and .mjs
extensions for route config file (#13931)
-
@react-router/dev
- Fix prerender file locations when cwd
differs from project root (#13824)
-
@react-router/dev
- Improve chunk error logging when a chunk cannot be found during the build (#13799)
-
@react-router/dev
- Fix incorrectly configured externalConditions
which had enabled module
condition for externals and broke builds with certain packages (like Emotion) (#13871)
Unstable Changes
⚠️ Unstable features are not recommended for production use
- Add unstable RSC support for Data Mode (#13700)
Changes by Package
Full Changelog: v7.6.3...v7.7.0