Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
7.4 KiB
7.4 KiB
Router Enhancement Module
Enhanced Routing with Guards, Middleware, and Analytics
The Router Enhancement Module provides advanced routing capabilities with access control, middleware, lazy loading, and analytics.
Features
- Route Guards - Access control for routes (auth, permissions, roles)
- Route Middleware - Cross-cutting concerns (analytics, loading, etc.)
- Lazy Route Loading - Load routes on demand
- Route Analytics - Track navigation patterns
- Integration with LiveComponents - Seamless integration with LiveComponent system
- History & Hash Modes - Support for both history and hash routing
Quick Start
Basic Usage
import { Router, BuiltInGuards, BuiltInMiddleware } from './modules/router/index.js';
// Create router
const router = Router.create({
mode: 'history',
base: '/',
enableAnalytics: true
});
// Register routes
router.routes([
{
path: '/',
component: () => '<div>Home</div>',
name: 'home',
title: 'Home'
},
{
path: '/dashboard',
component: () => '<div>Dashboard</div>',
name: 'dashboard',
title: 'Dashboard',
guards: ['auth'],
middleware: ['analytics', 'loading']
},
{
path: '/admin',
component: () => import('./components/Admin.js'),
name: 'admin',
title: 'Admin',
guards: ['auth', 'role:admin'],
lazy: true
}
]);
// Register guards
router.guard('auth', async (to, from) => {
const isAuthenticated = await checkAuth();
if (!isAuthenticated) {
return '/login'; // Redirect to login
}
return true; // Allow navigation
});
// Add global middleware
router.use(BuiltInMiddleware.analytics);
router.use(BuiltInMiddleware.scrollToTop);
// Navigate
await router.navigate('/dashboard');
API Reference
Router.create(config)
Create a new Router instance.
Parameters:
config.mode- Routing mode: 'history' or 'hash'config.base- Base pathconfig.enableAnalytics- Enable route analytics
router.route(path, config)
Register a single route.
Parameters:
path- Route pathconfig.component- Component (string, function, or HTMLElement)config.name- Route nameconfig.title- Page titleconfig.guards- Array of guard namesconfig.middleware- Array of middlewareconfig.lazy- Lazy load component
router.guard(name, guardFn)
Register a route guard.
Parameters:
name- Guard nameguardFn- Guard function:(to, from, context) => boolean | string
router.use(middleware)
Add global middleware.
Parameters:
middleware- Middleware instance, function, or built-in name
router.beforeEach(hook)
Add before navigation hook.
Parameters:
hook- Hook function:(to, from) => boolean | string | void
router.afterEach(hook)
Add after navigation hook.
Parameters:
hook- Hook function:(to, from) => void
router.navigate(path, options)
Navigate to a route.
Parameters:
path- Route pathoptions.container- Container elementoptions.updateHistory- Update browser history
Returns: Promise<boolean>
Route Guards
Authentication Guard
router.guard('auth', async (to, from) => {
if (!isAuthenticated()) {
return '/login';
}
return true;
});
// Use in route
router.route('/dashboard', {
component: DashboardComponent,
guards: ['auth']
});
Role Guard
router.guard('admin', async (to, from) => {
if (getUserRole() !== 'admin') {
return '/unauthorized';
}
return true;
});
// Use in route
router.route('/admin', {
component: AdminComponent,
guards: ['auth', 'admin']
});
Built-in Guards
// Use built-in guards
router.route('/dashboard', {
component: DashboardComponent,
guards: ['auth'] // Uses BuiltInGuards.auth
});
router.route('/login', {
component: LoginComponent,
guards: ['guest'] // Uses BuiltInGuards.guest
});
Route Middleware
Analytics Middleware
// Use built-in analytics middleware
router.use('analytics');
// Or custom middleware
router.use(RouteMiddleware.create('custom', async (to, from, next) => {
// Track navigation
analytics.track('page_view', { path: to.path });
next();
}));
Loading Middleware
router.use('loading'); // Shows loading indicator during navigation
Scroll to Top Middleware
router.use('scroll-to-top'); // Scrolls to top after navigation
Lazy Route Loading
router.route('/admin', {
component: () => import('./components/Admin.js'),
lazy: true
});
// Or with dynamic import
router.route('/user/:id', {
component: async (route) => {
const UserComponent = await import('./components/User.js');
return UserComponent.default(route.params.id);
},
lazy: true
});
Integration with LiveComponents
import { Router } from './modules/router/index.js';
import { LiveComponent } from './modules/livecomponent/index.js';
const router = Router.create();
router.route('/dashboard', {
component: async (route) => {
// Initialize LiveComponents after navigation
const container = document.querySelector('main');
container.innerHTML = '<div data-live-component="dashboard"></div>';
// Initialize LiveComponent
const component = container.querySelector('[data-live-component]');
LiveComponent.init(component);
return container;
}
});
Route Analytics
const router = Router.create({ enableAnalytics: true });
// Get analytics
const analytics = router.getAnalytics();
console.log('Total navigations:', analytics.totalNavigations);
console.log('Navigation history:', analytics.navigations);
// Listen for navigation events
window.addEventListener('router:navigation', (event) => {
const { to, from, timestamp } = event.detail;
console.log(`Navigated from ${from} to ${to}`);
});
Use Cases
Protected Routes
router.routes([
{
path: '/',
component: HomeComponent,
name: 'home'
},
{
path: '/dashboard',
component: DashboardComponent,
name: 'dashboard',
guards: ['auth']
},
{
path: '/admin',
component: AdminComponent,
name: 'admin',
guards: ['auth', 'admin']
}
]);
Route with Middleware
router.route('/api-data', {
component: ApiDataComponent,
middleware: ['analytics', 'loading']
});
Lazy Loading
router.route('/heavy-page', {
component: () => import('./pages/HeavyPage.js'),
lazy: true,
guards: ['auth']
});
Best Practices
- Use Guards for Access Control - Protect routes with guards
- Use Middleware for Cross-Cutting Concerns - Analytics, loading, etc.
- Lazy Load Heavy Routes - Improve initial load time
- Track Navigation - Use analytics to understand user behavior
- Handle Errors - Provide fallback routes for errors
Browser Support
- Chrome/Edge: 90+
- Firefox: 88+
- Safari: 14+
- Mobile: iOS 14+, Android Chrome 90+
Required Features:
- ES2020 JavaScript
- History API (for history mode)
- Promise support
Next: Analytics Module →