@dbs-portal/core-router
v1.0.0
Published
Type-safe routing functionality and navigation utilities for DBS Portal
Maintainers
Readme
@dbs-portal/core-router
Type-safe routing functionality and navigation utilities for DBS Portal using TanStack Router.
Features
- 🚀 Type-safe routing with TanStack Router integration
- 🔒 Authentication and authorization route guards
- 🧭 Navigation utilities and programmatic navigation
- 🍞 Automatic breadcrumb generation from route definitions
- 📱 History management and URL manipulation
- 🔧 Configurable router setup with fluent API
- 🎯 Seamless integration with DBS Portal architecture
- 🛡️ Route protection with customizable guards
- 📊 Navigation events and lifecycle hooks
- 🔄 State management integration ready
Installation
This package is part of the DBS Portal monorepo and should be installed via the workspace:
yarn workspace @dbs-portal/core-router installFor external projects:
npm install @dbs-portal/core-router @tanstack/react-router history
# or
yarn add @dbs-portal/core-router @tanstack/react-router historyQuick Start
1. Basic Router Setup
import { createAppRouter, setGlobalRouter } from '@dbs-portal/core-router'
// Create router with default configuration
const router = createAppRouter()
// Set as global router for navigation utilities
setGlobalRouter(router)
// Use in your React app
import { RouterProvider } from '@tanstack/react-router'
function App() {
return <RouterProvider router={router} />
}2. Advanced Configuration
import { configureRouter, createAppRouter } from '@dbs-portal/core-router'
const config = configureRouter()
.basePath('/app')
.preload('intent')
.scrollRestoration(true)
.devtools(true)
.build()
const router = createAppRouter(config)Core Concepts
Enhanced Permission System
The route registry includes a comprehensive permission system with multiple layers of protection and flexible configuration options.
Permission Configuration
Routes can be configured with detailed permission requirements:
import { route, strictRoute, protectedRoute } from '@dbs-portal/core-router/helpers'
// Basic permission check (user needs ANY of the specified permissions)
route('/users', 'User Management', () => import('@/pages/users'), {
permissions: ['users.read', 'users.manage'],
icon: 'users'
})
// Strict permission check (user needs ALL specified permissions)
strictRoute('/admin/system', 'System Administration', () => import('@/pages/admin/system'), {
permissions: ['admin.access', 'system.manage'],
icon: 'settings'
})
// Protected route with custom error handling
protectedRoute('/sensitive-data', 'Sensitive Data', () => import('@/pages/sensitive'), {
permissions: ['data.sensitive.access'],
permissionMode: 'all',
errorMessage: 'You need special clearance to access this data',
fallback: '/request-access',
icon: 'lock'
})Permission Modes
'any'(default): User needs at least ONE of the specified permissions'all': User needs ALL of the specified permissions
Permission Validation
Validate permissions before navigation or rendering:
import {
validateRoutePermissions,
getAllRequiredPermissions,
getRoutesByPermission,
canAccessAnyRoute
} from '@dbs-portal/core-router'
// Check if user can access a specific route
const validation = validateRoutePermissions('/admin/users', userPermissions)
if (!validation.allowed) {
console.log('Missing permissions:', validation.missingPermissions)
console.log('Error message:', validation.errorMessage)
console.log('Fallback route:', validation.fallbackRoute)
}
// Get all permissions required across the application
const allPermissions = getAllRequiredPermissions()
// Find routes that require a specific permission
const userManagementRoutes = getRoutesByPermission('users.manage')
// Check if user can access any routes (useful for navigation visibility)
const hasAnyAccess = canAccessAnyRoute(userPermissions)Runtime Permission Checking
Routes include runtime permission checks with detailed error handling:
import { createRoutesFromRegistry } from '@dbs-portal/core-router'
// Create routes with enhanced permission checking
const routes = createRoutesFromRegistry(parentRoute, userPermissions, {
enableRuntimeChecks: true, // Default: true
defaultFallback: '/unauthorized', // Default fallback route
permissionChecker: (requiredPermissions, userPermissions, mode) => {
// Custom permission checking logic
return mode === 'all'
? requiredPermissions.every(p => userPermissions.includes(p))
: requiredPermissions.some(p => userPermissions.includes(p))
}
})Permission Error Handling
When permission checks fail, detailed error information is provided:
// Error object includes:
{
routeId: '/admin/users',
fallbackRoute: '/unauthorized',
requiredPermissions: ['users.manage', 'admin.access'],
userPermissions: ['users.read'],
message: 'Access denied: Missing required permissions [users.manage, admin.access]'
}Route Guards
Route guards provide authentication and authorization protection for your routes:
import {
withAuthGuard,
withRoleGuard,
withPermissionGuard,
createCustomGuard
} from '@dbs-portal/core-router/guards'
// Authentication guard
const protectedRoute = withAuthGuard(route)
// Role-based guard
const adminRoute = withRoleGuard(route, 'admin')
const moderatorRoute = withRoleGuard(route, ['moderator', 'admin'])
// Permission-based guard
const manageUsersRoute = withPermissionGuard(route, 'users.manage')
// Custom guard
const customGuard = createCustomGuard((authState, route, location) => {
if (!authState.user?.isVerified) {
return '/verify-email'
}
return true
})Navigation Utilities
Programmatic navigation with type safety:
import {
navigate,
replace,
goBack,
goForward,
reload,
getCurrentLocation
} from '@dbs-portal/core-router/navigation'
// Navigate to a route
await navigate('/dashboard')
// Navigate with options
await navigate('/users/123', {
search: { tab: 'profile' },
state: { from: 'dashboard' }
})
// Replace current route
await replace('/login')
// History navigation
goBack()
goForward()
reload()
// Get current location
const location = getCurrentLocation()Breadcrumb Generation
Automatic breadcrumb generation from route metadata:
import {
generateBreadcrumbs,
breadcrumbUtils,
createBreadcrumbBuilder
} from '@dbs-portal/core-router/breadcrumbs'
// Register route metadata
breadcrumbUtils.registerRoutes({
'/': { title: 'Home' },
'/users': { title: 'Users' },
'/users/:id': {
title: 'User :id',
breadcrumb: { title: 'User Profile' }
}
})
// Generate breadcrumbs
const breadcrumbs = generateBreadcrumbs(currentRoute)
// Manual breadcrumb building
const customBreadcrumbs = createBreadcrumbBuilder()
.home('Dashboard', '/dashboard')
.add('Settings', '/settings')
.add('Profile', '/settings/profile')
.build()URL Utilities
Powerful URL manipulation and parsing:
import { urlUtils } from '@dbs-portal/core-router/navigation'
// Build URLs with parameters
const url = urlUtils.buildUrl('/users/:id', { id: '123' }, { tab: 'profile' })
// Result: '/users/123?tab=profile'
// Parse URLs
const parsed = urlUtils.parseUrl('https://example.com/users/123?tab=profile#section')
// Result: { path: '/users/123', search: { tab: 'profile' }, hash: 'section' }
// Pattern matching
const matches = urlUtils.matchesPattern('/users/123', '/users/:id') // trueIntegration with DBS Portal
Authentication Integration
import { setAuthStateGetter } from '@dbs-portal/core-router/guards'
import { useAuthStore } from '@dbs-portal/core-auth'
// Set up auth state integration
setAuthStateGetter(() => {
const authStore = useAuthStore.getState()
return {
isAuthenticated: authStore.isAuthenticated,
user: authStore.user
}
})State Management Integration
import { useRouterStore } from '@dbs-portal/core-store'
import { setGlobalRouter } from '@dbs-portal/core-router'
// Integrate with Zustand store
const router = createAppRouter()
setGlobalRouter(router)
// Listen to navigation events
router.addEventListener('afterNavigate', (event) => {
useRouterStore.getState().setCurrentRoute(event.to)
})API Reference
Router Configuration
createAppRouter(config?: RouterConfig): AppRouter
Creates an enhanced router instance with DBS Portal integrations.
Parameters:
config(optional): Router configuration options
Returns: Enhanced router instance
configureRouter(): RouterConfigBuilder
Creates a fluent configuration builder.
Example:
const config = configureRouter()
.basePath('/app')
.preload('intent')
.build()Navigation
navigate(path: string, options?: NavigationOptions): Promise<void>
Navigate to a specific path programmatically.
goBack(): void / goForward(): void
Navigate through browser history.
getCurrentLocation(): RouteInfo | null
Get current route information.
Route Guards
withAuthGuard<T>(route: T): T
Add authentication guard to a route.
withRoleGuard<T>(route: T, roles: string | string[]): T
Add role-based authorization guard.
withPermissionGuard<T>(route: T, permissions: string | string[]): T
Add permission-based authorization guard.
Breadcrumbs
generateBreadcrumbs(route: RouteInfo, config?: BreadcrumbGeneratorConfig): BreadcrumbItem[]
Generate breadcrumbs from route information.
breadcrumbUtils.registerRoute(path: string, metadata: RouteMetadata): void
Register route metadata for breadcrumb generation.
TypeScript Support
This package is built with TypeScript and provides comprehensive type definitions:
import type {
AppRouter,
RouteInfo,
RouteGuard,
NavigationOptions,
BreadcrumbConfig,
RouterConfig
} from '@dbs-portal/core-router'
// All exports are fully typed
const router: AppRouter = createAppRouter()
const guard: RouteGuard = (route, location) => trueTesting
The package includes comprehensive test coverage. Run tests with:
yarn testFor watch mode:
yarn test:watchExamples
Complete Setup Example
// router.ts
import {
createAppRouter,
configureRouter,
setGlobalRouter,
breadcrumbUtils
} from '@dbs-portal/core-router'
// Configure router
const config = configureRouter()
.basePath('/')
.preload('intent')
.scrollRestoration(true)
.devtools(process.env.NODE_ENV === 'development')
.build()
// Register route metadata
breadcrumbUtils.registerRoutes({
'/': { title: 'Home' },
'/dashboard': { title: 'Dashboard' },
'/users': { title: 'Users' },
'/users/:id': { title: 'User Profile' },
'/settings': { title: 'Settings' }
})
// Create and configure router
export const router = createAppRouter(config)
setGlobalRouter(router)Route Protection Example
// routes.ts
import { createRoute } from '@tanstack/react-router'
import { withAuthGuard, withRoleGuard } from '@dbs-portal/core-router/guards'
const dashboardRoute = withAuthGuard(
createRoute({
getParentRoute: () => rootRoute,
path: '/dashboard',
component: DashboardPage
})
)
const adminRoute = withRoleGuard(
createRoute({
getParentRoute: () => rootRoute,
path: '/admin',
component: AdminPage
}),
'admin'
)Dependencies
@tanstack/react-router^1.0.0 - Type-safe routinghistory^5.0.0 - Browser history management@dbs-portal/core-shared1.0.0 - Shared utilities and types
Peer Dependencies
react^19.0.0 - React framework
Contributing
This package follows the DBS Portal monorepo conventions. See the main repository documentation for contribution guidelines.
Simple Route Registration API
For a more intuitive developer experience, use the new simplified route registration system:
Register Simple Routes
import { route } from '@dbs-portal/core-router'
// Basic route
route('/settings', 'Settings', () => import('@/pages/settings'))
// Route with icon and permissions
route('/admin', 'Admin Panel', () => import('@/pages/admin'), {
icon: 'settings',
permissions: ['admin.access']
})Register Multiple Routes
import { routes } from '@dbs-portal/core-router'
routes([
['/animate', 'Animate', () => import('@/pages/components/animate')],
['/scroll', 'Scroll', () => import('@/pages/components/scroll')],
['/markdown', 'Markdown', () => import('@/pages/components/markdown')],
['/editor', 'Editor', () => import('@/pages/components/editor')],
['/multi-language', 'Multi Language', () => import('@/pages/components/multi-language')],
['/icon', 'Icons', () => import('@/pages/components/icon')],
['/upload', 'Upload', () => import('@/pages/components/upload')],
['/chart', 'Charts', () => import('@/pages/components/chart')]
])Register Route Groups
import { routeGroup } from '@dbs-portal/core-router'
routeGroup('Components', {
icon: 'component',
order: 1,
routes: [
['/animate', 'Animate', () => import('@/pages/components/animate')],
['/scroll', 'Scroll', () => import('@/pages/components/scroll')],
['/markdown', 'Markdown', () => import('@/pages/components/markdown')]
]
})Register Admin Routes
import { adminRoutes } from '@dbs-portal/core-router'
adminRoutes([
['/users', 'User Management', () => import('@/pages/admin/users')],
['/settings', 'System Settings', () => import('@/pages/admin/settings')],
['/audit', 'Audit Logs', () => import('@/pages/admin/audit')]
])Register Module Routes
import { moduleRoutes } from '@dbs-portal/core-router'
moduleRoutes('File Management', {
basePath: '/files',
icon: 'folder',
permissions: ['files.access'],
routes: [
['/', 'File Browser', () => import('./components/FileBrowser')],
['/upload', 'Upload Files', () => import('./components/FileUpload')],
['/settings', 'File Settings', () => import('./components/FileSettings')]
]
})Create Routes from Registry
import { createRoutesFromRegistry, getNavigation } from '@dbs-portal/core-router'
// Create routes from registry
const dynamicRoutes = createRoutesFromRegistry(appRoute, userPermissions)
// Generate navigation
const navigationStructure = getNavigation(userPermissions)License
MIT
