React Router Config Helpers
`react-router-config` is a utility package designed to provide static route configuration helpers, primarily for applications using React Router v4 and v5. It allows developers to define their application's routing structure as a centralized array of route objects, which is particularly useful for scenarios such as server-side data preloading, static analysis of routes, and programmatically linking to routes. The package offers two main functions: `matchRoutes` to identify matching routes for a given URL pathname, and `renderRoutes` to render the corresponding React components based on the matched configuration. Currently at version 5.1.1, this package is considered superseded and effectively abandoned for modern React Router applications. React Router v6 and later versions, which are now at v7, have integrated similar declarative and programmatic routing APIs (like `useRoutes` and `createBrowserRouter`) directly into their core, making `react-router-config` largely obsolete. Its last publication was over six years ago, further cementing its status as an unmaintained library.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'routes')
cause Attempting to use `react-router-config` (designed for v5) with React Router v6 or later. The underlying route object structure and APIs have changed significantly, making `matchRoutes` and `renderRoutes` unable to parse the new route definitions.fixUpgrade to React Router v6+ and refactor your routing logic to use the `useRoutes` hook or the `<Routes>` component, which supports object-based route configuration natively. -
Error: Invariant failed: You should not use <renderRoutes> outside a <Router>
cause The `renderRoutes` function, like other React Router components, relies on context provided by a parent `<Router>` component (e.g., `BrowserRouter`, `HashRouter`, `StaticRouter`). If `renderRoutes` is called without being a descendant of such a router, this error occurs.fixEnsure that the component calling `renderRoutes` is always rendered within a `BrowserRouter`, `HashRouter`, or `StaticRouter` from `react-router-dom`. -
ReferenceError: renderRoutes is not defined
cause This usually indicates an incorrect import statement, such as attempting to use CommonJS `require` in an ESM module context, or vice-versa, or an incorrect destructuring of the import.fixVerify that your import statement matches your module system (e.g., `import { renderRoutes } from 'react-router-config';` for ESM, or `const { renderRoutes } = require('react-router-config');` for CommonJS).
Warnings
- breaking `react-router-config` is incompatible with React Router v6 (and later v7) due to fundamental API changes. React Router v6 introduced the `useRoutes` hook and object-based routing directly into its core, deprecating the need for this separate package entirely.
- deprecated This package is effectively abandoned and unmaintained. Its last version (5.1.1) was published in 2019, predating the significant architectural shifts in React Router v6 and v7.
- gotcha The README explicitly states this is "alpha software" and needs more realistic examples for server rendering and pending navigation, indicating it might not be fully production-ready even for its target React Router v4/v5 versions.
- gotcha Route objects in `react-router-config` only accept the `component` prop for rendering; `render` or `children` render props, which are available in `<Route>` components of React Router v4/v5, are not supported.
- gotcha The `renderRoutes` function expects to be within a `React Router` context (e.g., `<BrowserRouter>`, `<StaticRouter>`). Calling it outside this context will result in an error.
Install
-
npm install react-router-config -
yarn add react-router-config -
pnpm add react-router-config
Imports
- matchRoutes
const matchRoutes = require('react-router-config').matchRoutes;import { matchRoutes } from 'react-router-config'; - renderRoutes
const renderRoutes = require('react-router-config').renderRoutes;import { renderRoutes } from 'react-router-config'; - UMD Global
<script src="https://unpkg.com/react-router-config/umd/react-router-config.min.js"></script> window.ReactRouterConfig.matchRoutes;
Quickstart
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Link } from 'react-router-dom'; // Requires react-router-dom v5.x or lower
import { matchRoutes, renderRoutes } from 'react-router-config';
// Define your React components
const Home = () => <h2>Home Page</h2>;
const Child = ({ route, match }) => (
<div>
<h3>Child Component: {match.params.id}</h3>
<Link to={`${match.url}/grand-child`}>Go to Grand Child</Link>
{/* Recursively render sub-routes */}
{renderRoutes(route.routes, { extraProp: 'passedValue' })}
</div>
);
const GrandChild = () => <h4>Grand Child Component</h4>;
const NotFound = () => <h2>404 Not Found</h2>;
// Define the static route configuration
const routes = [
{
path: '/',
exact: true,
component: Home,
},
{
path: '/child/:id',
component: Child,
routes: [
{
path: '/child/:id/grand-child',
component: GrandChild,
},
],
},
{ // A catch-all route for unmatched paths
component: NotFound,
},
];
// Example usage: matching routes for a specific path
const path = '/child/123';
const branch = matchRoutes(routes, path);
console.log(`Matched routes for ${path}:`, branch.map(b => b.route.path || b.route.component.name));
// The main App component that uses renderRoutes to display the current route
const App = () => (
<BrowserRouter>
<nav>
<Link to="/">Home</Link> | <Link to="/child/456">Child 456</Link> |
<Link to="/child/789/grand-child">Grand Child</Link> |
<Link to="/non-existent">Non-Existent</Link>
</nav>
<hr />
{/* Renders the top-level routes and their nested structures */}
{renderRoutes(routes)}
</BrowserRouter>
);
// Render the application
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);