Adding New Pages
BunShip Pro uses TanStack Router with file-based routing. Create a file and you have a route.How Routing Works
Routes live inapps/web/src/routes/. The file name becomes the URL path:
| File | URL |
|---|---|
routes/index.tsx | / |
routes/_app/dashboard.tsx | /dashboard |
routes/_app/organizations_.$orgId/members.tsx | /organizations/:orgId/members |
routes/_marketing/pricing.tsx | /pricing |
Layout Groups
Files are organized into layout groups using the underscore prefix:| Prefix | Layout | Purpose |
|---|---|---|
_app/ | Authenticated layout with sidebar | Dashboard, settings, org pages |
_auth/ | Minimal centered layout | Login, register, password reset |
_marketing/ | Marketing header/footer | Pricing, blog, contact, legal |
_app.tsx) wraps all pages in that group with shared UI — sidebar, header, auth protection.
Adding a Dashboard Page
- Create a file in
routes/_app/:
- The page is now accessible at
/analytics(authentication required automatically via the_applayout).
Adding an Organization Page
Organization pages are scoped to a specific org and have access to the org ID from the URL:/organizations/:orgId/reports.
Adding to the Sidebar
The sidebar navigation is defined inapps/web/src/components/sidebar.tsx. There are two navigation arrays:
Main Navigation
Add items to theDEFAULT_SECTIONS array:
Organization Navigation
Add items to theALL_ORG_ITEMS array. Each item belongs to either the org section (user-facing) or dev section (developer tools):
lucide-react.
Protecting Pages by Role
The organization layout provides role context. Use theuseOrgContext() hook to check the current user’s role:
Role Hierarchy
Roles are hierarchical:owner > admin > member > viewer. Permissions are defined in packages/config/src/features.ts:
Adding a Marketing Page
Marketing pages use the_marketing layout with the public header and footer:
apps/web/src/components/marketing-header.tsx.
Next Steps
- UI Components — Available components for building page content
- Configuration — Feature flags and RBAC settings

