Skip to content

defineRoutes

defineRoutes(routeMap): ResolvedRoutes<T>

Creates a fully typed route object from a nested plain object.

  • Every path is a genuine primitive string — use it directly anywhere a string is expected (e.g. <Route path={...} />).
  • Static paths gain .build(query?, options?) and .buildRelative(query?, options?).
  • Dynamic paths (containing :param) and splat paths (trailing /*) gain:
    • .build(params, query?, options?) and .buildRelative(...) — resolves the template into a concrete URL
    • .paramNames — array of the param names extracted from the template (a splat is reported as ['*'])

Nesting is unlimited — organize routes into as many groups and sub-groups as your app needs.

defineRoutes() also validates every template in development (no-op in production), warning on missing leading /, non-trailing *, duplicate path templates, and static routes shadowed by a dynamic route defined above them. See Route Validation.

ts
const PATHS = defineRoutes({
  SERVICES: {
    ROOT: "/services",
    SUPPORT_CENTER: {
      DETAILS: "/services/support-center/:id",
      EDIT: "/services/support-center/edit/:id",
    },
  },
} as const);

PATHS.SERVICES.ROOT; // '/services'
PATHS.SERVICES.SUPPORT_CENTER.EDIT.build({ id: 7 });
// → '/services/support-center/edit/7'

PATHS.SERVICES.SUPPORT_CENTER.EDIT.build(
  { id: 7 },
  { tab: "info" },
  { hash: "details" },
);
// → '/services/support-center/edit/7?tab=info#details'

PATHS.SERVICES.SUPPORT_CENTER.EDIT.paramNames; // ['id']

Always pass as const to defineRoutes() — it preserves the literal string types that power .build()'s compile-time param checking.

Route Types

Route typeExampleBehaves asGains
StaticHOME: '/'A primitive string (its template).build(query?, options?) and .buildRelative(...)
DynamicDETAILS: '/users/:id'A primitive string (its template).build(params, query?, options?), .buildRelative(...), and .paramNames
SplatFILES: '/files/*'A primitive string (its template).build(params, query?, options?), .buildRelative(...), and .paramNames

defineRoutes() walks your route object recursively, returning each path as a genuine primitive string. .build(), .buildRelative(), and .paramNames on dynamic paths are attached to String.prototype once, so both static and dynamic routes can carry a query string or hash. Dynamic paths (containing a :param segment or a trailing /* splat) additionally gain .paramNames. See Known Behaviours & Gotchas for details.

Released under the MIT License.