Utility library for React Router v7 - Automatically build routes from file-system with support for modules and API handlers.
- π― Type-safe - Full TypeScript support with comprehensive type definitions
- π File-based routing - Automatically build routes from directory structure
- π§© Module-based - Organize code by independent modules
- π API routes - Support for building API handlers
- π¦ ESM & CommonJS - Dual module support for maximum compatibility
- β‘ Zero dependencies - Only peer dependencies on React and React Router v7
npm install modules-page-routingPeer Dependencies:
npm install react react-routerOrganize your code using a module-based structure:
app/
βββ modules/
β βββ __root.tsx # Shared layout for all modules
β βββ __homepage.tsx # Homepage (index route)
β βββ auth/
β β βββ pages/
β β βββ _layout.tsx # Layout for auth module
β β βββ sign-in.tsx # /auth/sign-in
β β βββ sign-up.tsx # /auth/sign-up
β β βββ forgot-password.tsx
β βββ admin/
β β βββ pages/
β β βββ _layout.tsx # Layout for admin module
β β βββ index.tsx # /admin (index route)
β β βββ users/
β β β βββ index.tsx # /admin/users
β β β βββ [id].tsx # /admin/users/:id
β β βββ settings.tsx # /admin/settings
β βββ shop/
β βββ pages/
β βββ index.tsx # /shop
β βββ products/
β β βββ index.tsx # /shop/products
β β βββ [id].tsx # /shop/products/:id
β βββ cart.tsx # /shop/cart
βββ api/
β βββ v1/
β βββ users.ts # API: /api/v1/users
β βββ users.$id.ts # API: /api/v1/users/:id
β βββ products.search.ts # API: /api/v1/products/search
βββ routes.ts
import {
index,
layout,
prefix,
type RouteConfig,
} from '@react-router/dev/routes';
import { flatRoutes } from '@react-router/fs-routes';
import { buildApiRouteConfig } from 'modules-page-routing';
import { buildGlobRouteConfig, type GlobModules } from 'modules-page-routing';
// Import all files in modules/*/pages/* and api/**/*
const globTree = import.meta.glob('./modules/**/pages/**/*.{tsx,ts}');
const apiTree = import.meta.glob('./api/**/*.ts');
// Build React Router v7 RouteConfig from glob
const moduleRoutes = buildGlobRouteConfig(globTree as GlobModules);
const apiRoutes = buildApiRouteConfig(apiTree);
const routes = [
// All module pages are nested under a shared layout
layout('modules/__root.tsx', [
index('modules/__homepage.tsx'),
...moduleRoutes,
]),
// API routes with /api prefix
...prefix('api', apiRoutes),
// Routes from app/routes/** (optional - if you still want traditional file-based routing)
...(await flatRoutes({
rootDirectory: 'routes',
})),
];
export default routes satisfies RouteConfig;-
index.tsxβ Index route of the module/foldermodules/admin/pages/index.tsxβ/adminmodules/admin/pages/users/index.tsxβ/admin/users
-
_layout.tsxβ Layout wrapper for child routesmodules/admin/pages/_layout.tsxβ Layout for all routes in/admin/*modules/admin/pages/users/_layout.tsxβ Layout for/admin/users/*
-
[param].tsxβ Dynamic route parametermodules/admin/pages/users/[id].tsxβ/admin/users/:idmodules/shop/pages/products/[slug].tsxβ/shop/products/:slug
-
[...rest].tsxβ Catch-all/splat routemodules/docs/pages/[...path].tsxβ/docs/*
-
_not-found.tsxβ 404 page for the modulemodules/admin/pages/_not-found.tsxβ 404 for/admin/*
API routes use a different convention:
-
filename.tsβ Single segmentapi/v1/users.tsβ/api/v1/users
-
filename.segment.tsβ Multiple segments (using.)api/v1/products.search.tsβ/api/v1/products/searchapi/v1/orders.export.csv.tsβ/api/v1/orders/export/csv
-
filename.$param.tsβ Dynamic parameter (using$prefix)api/v1/users.$id.tsβ/api/v1/users/:idapi/v1/posts.$slug.comments.tsβ/api/v1/posts/:slug/comments
import { Outlet } from 'react-router';
export default function AdminLayout() {
return (
<div className='admin-layout'>
<aside>
<nav>
<a href='/admin'>Dashboard</a>
<a href='/admin/users'>Users</a>
<a href='/admin/settings'>Settings</a>
</nav>
</aside>
<main>
<Outlet /> {/* Render nested routes */}
</main>
</div>
);
}import { useParams } from 'react-router';
export default function UserDetail() {
const { id } = useParams();
return (
<div>
<h1>User Detail: {id}</h1>
{/* Your component code */}
</div>
);
}import type { LoaderFunctionArgs } from 'react-router';
export async function loader({ params }: LoaderFunctionArgs) {
const userId = params.id;
// Fetch user data
const user = await fetchUser(userId);
return Response.json(user);
}
export async function action({ request, params }: LoaderFunctionArgs) {
const userId = params.id;
const data = await request.json();
// Update user
await updateUser(userId, data);
return Response.json({ success: true });
}Builds React Router v7 RouteConfig from Vite import.meta.glob().
Parameters:
globModules: Object returned fromimport.meta.glob('./modules/**/pages/**/*.{tsx,ts}')
Returns: Array of RouteConfigNode to use with React Router v7 config
Conventions:
- Files in
modules/<module>/pages/**/*β URL/<module>/**/* _layout.tsxβ Layout wrapper with<Outlet />index.tsxβ Index route[param]β Dynamic parameter[...rest]β Catch-all route_not-found.tsxβ 404 handler
Builds API route config from Vite import.meta.glob().
Parameters:
globModules: Object returned fromimport.meta.glob('./api/**/*.ts')
Returns: Array of RouteConfigNode to use with prefix('api', ...)
Conventions:
api/v1/users.tsβ/api/v1/usersapi/v1/users.$id.tsβ/api/v1/users/:idapi/v1/products.search.tsβ/api/v1/products/search.in filename β additional path segment$prefix β dynamic parameter
This library is written entirely in TypeScript with full type definitions:
import type { GlobModules, RouteConfigNode } from 'modules-page-routing';β Automatic - No need to manually define routes, just create files following conventions
β Module-based - Organize code by features/modules, easy to scale
β Type-safe - Full TypeScript support
β Flexible - Can be combined with traditional file-based routing
β
Nested layouts - Support for nested layouts with _layout.tsx
β API routes - Build both UI routes and API endpoints the same way
See complete examples at: https://github.com/sonicname/modules-page-routing/tree/development/example
MIT
Contributions are welcome! Please feel free to submit a Pull Request or create an Issue on GitHub.
https://github.com/sonicname/modules-page-routing
If you encounter any issues or have questions, please create an issue on the GitHub repository.