Getting Started
Installation
npm install react-routes-forge
# or
pnpm add react-routes-forge
# or
yarn add react-routes-forge
# or
bun add react-routes-forgeNote: this package ships dual ESM + CommonJS builds. See Known Behaviours for details.
Define Your Routes
Create a single file — typically paths.ts — as the source of truth for all routes:
// paths.ts
import { defineRoutes } from "react-routes-forge";
export const PATHS = defineRoutes({
HOME: "/",
LOGIN: "/login",
USERS: {
ROOT: "/users",
ADD: "/users/add",
EDIT: "/users/edit/:id",
DETAILS: "/users/:id",
},
ROLES: {
PERMISSIONS: "/roles/permissions/:name",
},
} as const);Always pass
as const— it preserves the literal string types that power.build()'s compile-time param checking. Without it, TypeScript widens your path strings to genericstringand you lose type safety.
Use in Your Router
Static paths and dynamic templates both work directly as strings in <Route path={...} />:
// App.tsx
import { Routes, Route } from "react-router-dom";
import { PATHS } from "./paths";
<Routes>
<Route path={PATHS.HOME} element={<Home />} />
<Route path={PATHS.USERS.ROOT} element={<UserList />} />
<Route path={PATHS.USERS.EDIT} element={<EditUser />} />
<Route path={PATHS.ROLES.PERMISSIONS} element={<RolePermissions />} />
</Routes>;Navigate with Type Safety
Call .build() to resolve a dynamic path into a real URL — params are type-checked from the template:
import { useNavigate } from "react-router-dom";
function MyComponent() {
const navigate = useNavigate();
// ↓ Param type-checked from the template ":id"
navigate(PATHS.USERS.EDIT.build({ id: 42 })); // → '/users/edit/42'
navigate(PATHS.ROLES.PERMISSIONS.build({ name: "admin" })); // → '/roles/permissions/admin'
navigate(PATHS.HOME); // → '/' (static paths work directly)
}Route Validation
In development, defineRoutes() warns via console.warn about likely mistakes — a missing leading /, non-trailing splats, duplicate path templates, and static routes shadowed by a dynamic route defined above them:
defineRoutes({
A: { FOO: "/foo" },
B: { FOO: "/foo" },
} as const);
// ⚠ console.warn: [route-forge] Duplicate route path "/foo" for "A.FOO" and "B.FOO".
defineRoutes({
USERS: { DETAILS: "/users/:id", ME: "/users/me" },
} as const);
// ⚠ console.warn: [route-forge] Route "USERS.ME" ("/users/me") is shadowed by
// dynamic route "USERS.DETAILS" ("/users/:id").These are warnings, not errors — invalid routes still build, so a broken definition can't crash your app at import time. Order matters: put static routes before dynamic parameter routes that could swallow them.
What's Next?
- API Reference — start with
defineRoutes - React Hooks — typed hooks for React Router
- Query & Hash Support — attaching query strings and hash fragments