React Router
A configuration-based router for React. Routes are registered as data on a singleton (router.add("/users/:id", UserPage)), rendered by one internal wrapper, and reach into browser globals (history, popstate, location) directly. Trades the composability of JSX routes for a simpler mental model: one global table, one render path, one place for middleware and lazy-loading.
Highlighted features
Routes as data
router.add(“/users/:id”, UserPage) on a singleton. One global table; refactor without touching JSX trees.
Locale-aware URLs
/en/admin/users, /fr/admin/users generated from one route declaration. changeLocaleCode swaps the prefix without re-mounting.
Middleware per route
Array of components returning null / NAVIGATING / ReactNode. Auth guards, role checks, redirect-before-render — composable per route or per group.
Lazy apps + modules
setApps([…]) wires app/module loader pairs. Code-splits at the route boundary; bundles per app instead of per page.
Prefetch on <Link> hover
Lazy chunks start loading the moment the user hovers a link. Opt out per-link with prefetch={false} when bandwidth matters.
Chunk-error recovery
lazyLoading.chunkErrorHandler recovers after deploys when a stale tab requests a hashed chunk that no longer exists. Hard-reload, fallback page, custom — your choice.
Install
npm install @mongez/react-routeryarn add @mongez/react-routerpnpm add @mongez/react-routerPeer deps: react >= 18, react-dom >= 18.
Quick peek
import router, { Link, setRouterConfigurations } from "@mongez/react-router";
router.add("/", HomePage);router.add("/users/:id", UserPage, [authMiddleware]);
setRouterConfigurations({ localization: { defaultLocaleCode: "en", localeCodes: ["en", "fr"] },});
router.scan(); // mounts <RouterWrapper> into #root
// In any component:<Link to="/users/42">User 42</Link>Register routes as data on the singleton, configure locale-prefixed URLs, then call router.scan() to mount the renderer.
Mental model
declare router.add("/users/:id", UserPage); router.add("/about", AboutPage, [authMiddleware]);
configure setRouterConfigurations({ localization: {...}, lazyLoading: {...} });
boot router.scan(); // mounts <RouterWrapper> into #root // parses URL, fires "navigating", // renders the matching route
run <Link to="/about"> // intercepts clicks → router.goTo navigateTo("/about") // imperative; from anywhere popstate (back/forward) // detected automatically ↓ router.refresh(mode) ↓ "navigating" + "rendering" events ↓ <RouterWrapper> picks route, runs middleware, rendersOne wrapper handles every navigation type. Middleware, lazy-loading, and not-found handling all live inside that one render path.
Scope vs. alternatives
| Need | This package | Alternative |
|---|---|---|
Tree-shape routing (<Routes> / <Route> JSX) | ✗ — singleton-imperative | react-router-dom |
| Data loaders & actions with route-level revalidation | ✗ — bring your own (@mongez/atomic-query for cache) | react-router@6.4+ data API |
| Type-safe paths (compile-time URL params) | ✗ — params are Record<string, any> | @tanstack/router |
| Lazy-loaded app + module providers | ✓ | DIY with React.lazy |
Locale prefix in path (/en/admin/users) | ✓ | DIY |
| Chunk-error recovery after deploys | ✓ | DIY |
Prefetch lazy chunks on <Link> hover | ✓ | DIY |
| Middleware per route + per group | ✓ | react-router@6.4+ loaders, @tanstack/router beforeLoad |
Where to go next
- Routes —
router.add, route shapes, dynamic segments - Navigation —
Link,navigateTo,navigateBack,silentNavigation - Params — URL params, query-string integration
- Lazy loading —
setApps, app/module loader pairs, prefetch - Localization — locale-prefixed URLs,
changeLocaleCode - Recipes — common patterns