New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

modules-page-routing

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

modules-page-routing

Utility library for React Router v7 - helpers for routing, navigation, and page management

latest
Source
npmnpm
Version
0.1.22
Version published
Weekly downloads
3
-66.67%
Maintainers
1
Weekly downloads
 
Created
Source

modules-page-routing

Utility library for React Router v7 - Automatically build routes from file-system with support for modules and API handlers.

Features

  • 🎯 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 (global and module-scoped)
  • 📦 ESM & CommonJS - Dual module support for maximum compatibility
  • Zero dependencies - Only peer dependencies on React and React Router v7

Installation

npm install modules-page-routing

Peer Dependencies:

npm install react react-router

Usage

1. Directory Structure

Organize 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/
│       ├── api/
│       │   ├── products.ts            # API: /api/shop/products
│       │   └── products.$id.ts        # API: /api/shop/products/:id
│       └── 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

2. routes.ts File

import {
  index,
  layout,
  prefix,
  type RouteConfig,
} from '@react-router/dev/routes';
import { flatRoutes } from '@react-router/fs-routes';
import {
  buildApiRouteConfig,
  buildApiModuleRouteConfig,
  buildGlobRouteConfig,
  type GlobModules,
} from 'modules-page-routing';

// Import all files in modules/*/pages/*, modules/*/api/*, and api/**/*
const globTree = import.meta.glob('./modules/**/pages/**/*.{tsx,ts}');
const apiTree = import.meta.glob('./api/**/*.ts');
const apiModuleTree = import.meta.glob('./modules/**/api/**/*.ts');

// Build React Router v7 RouteConfig from glob
const moduleRoutes = buildGlobRouteConfig(globTree as GlobModules);
const apiRoutes = buildApiRouteConfig(apiTree);
const apiModuleRoutes = buildApiModuleRouteConfig(apiModuleTree);

const routes = [
  // All module pages are nested under a shared layout
  layout('modules/__root.tsx', [
    index('modules/__homepage.tsx'),
    ...moduleRoutes,
  ]),

  // API routes: global (/api/v1/...) + module-scoped (/api/<module>/...)
  ...prefix('api', [...apiRoutes, ...apiModuleRoutes]),

  // Routes from app/routes/** (optional - if you still want traditional file-based routing)
  ...(await flatRoutes({
    rootDirectory: 'routes',
  })),
];

export default routes satisfies RouteConfig;

3. File Naming Conventions

Module Pages

  • index.tsx → Index route of the module/folder

    • modules/admin/pages/index.tsx/admin
    • modules/admin/pages/users/index.tsx/admin/users
  • _layout.tsx → Layout wrapper for child routes

    • modules/admin/pages/_layout.tsx → Layout for all routes in /admin/*
    • modules/admin/pages/users/_layout.tsx → Layout for /admin/users/*
  • [param].tsx → Dynamic route parameter

    • modules/admin/pages/users/[id].tsx/admin/users/:id
    • modules/shop/pages/products/[slug].tsx/shop/products/:slug
  • [...rest].tsx → Catch-all/splat route

    • modules/docs/pages/[...path].tsx/docs/*
  • _not-found.tsx → 404 page for the module

    • modules/admin/pages/_not-found.tsx → 404 for /admin/*
  • _error.tsx → Error boundary for the module (used by buildGlobRoutes runtime)

    • modules/admin/pages/_error.tsx → Error boundary for /admin/*
    • modules/admin/pages/users/_error.tsx → Error boundary for /admin/users/*
  • _loading.tsx → Loading fallback for the module (replaces default Suspense fallback)

    • modules/admin/pages/_loading.tsx → Loading UI for /admin/*
    • modules/admin/pages/users/_loading.tsx → Loading UI for /admin/users/*
  • _<folder> or _<file>.tsx → Parentless route (escapes parent layout)

    • modules/auth/pages/_login/index.tsx/auth/login (without auth layout)
    • modules/admin/pages/_fullscreen-editor.tsx/admin/fullscreen-editor (without admin layout)
    • Useful for modal pages, login overlays, or pages that need a different layout
  • (group) → Route group (organizational only, no URL segment)

    • modules/admin/pages/(dashboard)/overview.tsx/admin/overview
    • modules/admin/pages/(settings)/profile.tsx/admin/profile
    • Supports _layout.tsx inside route groups for shared layouts within the group
    • Example structure:
      admin/pages/
      ├── (dashboard)/
      │   ├── _layout.tsx    # Layout for dashboard group
      │   ├── index.tsx      # /admin
      │   └── analytics.tsx  # /admin/analytics
      └── (settings)/
          ├── _layout.tsx    # Layout for settings group
          ├── profile.tsx    # /admin/profile
          └── security.tsx   # /admin/security
      

API Routes

API routes use a different convention:

  • filename.ts → Single segment

    • api/v1/users.ts/api/v1/users
  • filename.segment.ts → Multiple segments (using .)

    • api/v1/products.search.ts/api/v1/products/search
    • api/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/:id
    • api/v1/posts.$slug.comments.ts/api/v1/posts/:slug/comments

Module-scoped API Routes

API handlers can also live inside each module's api/ directory, co-located with pages:

  • modules/auth/api/login.ts/api/auth/login
  • modules/shop/api/products.ts/api/shop/products
  • modules/shop/api/products.$id.ts/api/shop/products/:id
  • modules/admin/api/v1/users.ts/api/admin/v1/users

Same naming conventions apply (. for segments, $ for params, _ for parentless, (group) for groups).

4. Component Examples

Module Layout (modules/admin/pages/_layout.tsx)

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>
  );
}

Module Page (modules/admin/pages/users/[id].tsx)

import { useParams } from 'react-router';

export default function UserDetail() {
  const { id } = useParams();

  return (
    <div>
      <h1>User Detail: {id}</h1>
      {/* Your component code */}
    </div>
  );
}

API Handler (api/v1/users.$id.ts)

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 });
}

API Reference

buildGlobRouteConfig(globModules: GlobModules): RouteConfigNode[]

Builds React Router v7 RouteConfig from Vite import.meta.glob().

Parameters:

  • globModules: Object returned from import.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
  • _<folder> or _<file>.tsx → Parentless route (escapes parent layout)

buildApiRouteConfig(globModules: Record<string, unknown>): RouteConfigNode[]

Builds API route config from a global api/ directory.

Parameters:

  • globModules: Object returned from import.meta.glob('./api/**/*.ts')

Returns: Array of RouteConfigNode to use with prefix('api', ...)

Conventions:

  • api/v1/users.ts/api/v1/users
  • api/v1/users.$id.ts/api/v1/users/:id
  • api/v1/products.search.ts/api/v1/products/search
  • . in filename → additional path segment
  • $ prefix → dynamic parameter
  • _ prefix in folder/filename → Parentless route (stripped from URL)

buildApiModuleRouteConfig(globModules: Record<string, unknown>): RouteConfigNode[]

Builds API route config from module-scoped api/ directories. Each module can co-locate its API handlers alongside its pages.

Parameters:

  • globModules: Object returned from import.meta.glob('./modules/**/api/**/*.ts')

Returns: Array of RouteConfigNode to use with prefix('api', ...)

Mapping: modules/<module>/api/<rest>/api/<module>/<rest>

Examples:

  • modules/auth/api/login.ts/api/auth/login
  • modules/admin/api/users.$id.ts/api/admin/users/:id
  • modules/shop/api/orders.export.ts/api/shop/orders/export

Conventions: Same as buildApiRouteConfig. for segments, $ for params, _ for parentless, (group) for route groups.

CLI

Visualize and validate your route tree from the terminal.

Route Tree

npx modules-page-routing routes --dir ./app
Page Routes

  /admin                             modules/admin/pages/_layout.tsx
  ├── (index)                        modules/admin/pages/index.tsx
  ├── /users                         modules/admin/pages/users/index.tsx
  ├── /users/:id                     modules/admin/pages/users/[id].tsx
  ├── /settings                      modules/admin/pages/settings.tsx
  └── /*                             modules/admin/pages/_not-found.tsx
  /auth                              modules/auth/pages/_layout.tsx
  ├── /sign-in                       modules/auth/pages/sign-in.tsx
  └── /sign-up                       modules/auth/pages/sign-up.tsx

API Routes

  /api/shop/products                 modules/shop/api/products.ts
  /api/shop/products/:id             modules/shop/api/products.$id.ts

Use --json for machine-readable output.

Validate

npx modules-page-routing validate --dir ./app

Checks for:

RuleSeverityDescription
duplicate-patherrorTwo files resolve to the same URL
dynamic-conflicterror[id].tsx and [slug].tsx in the same directory
catchall-shadowwarnCatch-all * route may shadow siblings
orphan-special-filewarn_error.tsx/_loading.tsx without _layout.tsx
empty-modulewarnModule has no page files
missing-indexwarnHas _layout.tsx but no index.tsx

Exits with code 1 if any errors are found — useful in CI.

TypeScript Support

This library is written entirely in TypeScript with full type definitions:

import type { GlobModules, RouteConfigNode } from 'modules-page-routing';

Benefits

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

Real-world Example

See complete examples at: https://github.com/sonicname/modules-page-routing/tree/development/example

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request or create an Issue on GitHub.

Repository

https://github.com/sonicname/modules-page-routing

If you encounter any issues or have questions, please create an issue on the GitHub repository.

Keywords

react-router

FAQs

Package last updated on 01 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts