Registers a new admin or public route in core-routes, core-workspace, workspace-routes, and sidebar navigation. Use when adding a new route for a feature that needs to be wired into the routing system.
Registers a new route across the entire routing chain. This involves up to 6 files depending on whether it's an admin or public route.
$ARGUMENTS[0] = Route type: admin or public$ARGUMENTS[1] = Segment name in kebab-case (e.g., invoices, notifications)$ARGUMENTS[2] = (Optional) Additional context like the feature package nameAdding a route in this project requires updating files in this order:
packages/core-routes/src/lib/routes.ts — Add SEGMENTS constant + ADMIN_ROUTES entriespackages/core-routes/src/lib/route-builders.ts — Add adminUrlBuilders entriespackages/core-routes/src/lib/hooks/use-workspace-routes.ts — Add workspace route methodspackages/core-workspace/src/lib/provider/workspace-provider.tsx — Add to defaultRoutesapps/maas-app/src/app/routes/workspace-routes.tsx — Mount the Route componentapps/maas-app/src/app/hooks/use-main-navigation.tsx — Add sidebar nav itempackages/core-routes/src/lib/routes.ts — Add SEGMENTS constant + PUBLIC_ROUTES entrypackages/core-routes/src/lib/hooks/use-public-routes.ts — Add public route methodapps/maas-app/src/app/routes/root-routes.tsx — Mount the Route componentIn packages/core-routes/src/lib/routes.ts:
// In SEGMENTS object (if the segment doesn't exist yet):
MY_ENTITY: 'my-entities',
// In ADMIN_ROUTES object:
MY_ENTITIES: SEGMENTS.MY_ENTITY,
MY_ENTITIES_WILDCARD: `${SEGMENTS.MY_ENTITY}/*`,
MY_ENTITY_NEW: `${SEGMENTS.MY_ENTITY}/${SEGMENTS.NEW}`,
MY_ENTITY_EDIT: `${SEGMENTS.MY_ENTITY}/:myEntityId`,
Follow existing patterns for naming:
{ENTITY}, {ENTITY}_WILDCARD, {ENTITY}_NEW, {ENTITY}_EDIT{ENTITY}_INFO, {ENTITY}_DETAILS, etc.PMS_{ENTITY}, PMS_{ENTITY}_WILDCARD, etc.In packages/core-routes/src/lib/route-builders.ts, add to adminUrlBuilders:
// Simple CRUD entity
myEntities: () => ADMIN_ROUTES.MY_ENTITIES,
myEntityNew: () => `${SEGMENTS.MY_ENTITY}/${SEGMENTS.NEW}`,
myEntityEdit: (myEntityId: string) => buildPath(`${SEGMENTS.MY_ENTITY}/:myEntityId`, { myEntityId }),
In packages/core-routes/src/lib/hooks/use-workspace-routes.ts, add to the returned object:
/** My entities list URL */
myEntities: () => `${baseUrl}/${adminUrlBuilders.myEntities()}`,
/** New my entity URL */
myEntityNew: () => `${baseUrl}/${adminUrlBuilders.myEntityNew()}`,
/** Edit my entity URL */
myEntityEdit: (myEntityId: string) => `${baseUrl}/${adminUrlBuilders.myEntityEdit(myEntityId)}`,
In packages/core-workspace/src/lib/provider/workspace-provider.tsx, add to defaultRoutes:
myEntities: () => '/my-entities',
myEntityNew: () => '/my-entities/new',
myEntityEdit: () => '/my-entities',
In apps/maas-app/src/app/routes/workspace-routes.tsx:
// Import
import { MyEntitiesRoutes } from '@maas/web-feature-my-entities';
// Mount (inside the <Routes> element that's inside <AdminLayout>)
<Route path={ADMIN_ROUTES.MY_ENTITIES_WILDCARD} element={<MyEntitiesRoutes />} />
In apps/maas-app/src/app/hooks/use-main-navigation.tsx:
// Import the icon
import { SomeIcon } from 'lucide-react';
// Add to the appropriate section
{
title: 'My Entities',
url: routes.myEntities(),
icon: SomeIcon,
},
In packages/core-routes/src/lib/routes.ts:
// In SEGMENTS (if needed):
MY_PAGE: 'my-page',
// In PUBLIC_ROUTES:
MY_PAGE: `/${SEGMENTS.MY_PAGE}`,
In packages/core-routes/src/lib/hooks/use-public-routes.ts:
/** My page URL */
myPage: PUBLIC_ROUTES.MY_PAGE,
/** My page detail URL */
myPageDetail: (id: string) => `${PUBLIC_ROUTES.MY_PAGE}/${id}`,
In apps/maas-app/src/app/routes/root-routes.tsx, inside the public Layout:
<Route path="/my-page/*" element={<MyPageRoutes />} />
After adding routes, run:
npx nx typecheck @maas/core-routes
npx nx typecheck @maas/core-workspace
npx nx typecheck @maas/maas-app
This ensures all route types are consistent across the chain.