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
365 lines
7.4 KiB
Markdown
365 lines
7.4 KiB
Markdown
# 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
|
|
|
|
```javascript
|
|
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 path
|
|
- `config.enableAnalytics` - Enable route analytics
|
|
|
|
### router.route(path, config)
|
|
|
|
Register a single route.
|
|
|
|
**Parameters**:
|
|
- `path` - Route path
|
|
- `config.component` - Component (string, function, or HTMLElement)
|
|
- `config.name` - Route name
|
|
- `config.title` - Page title
|
|
- `config.guards` - Array of guard names
|
|
- `config.middleware` - Array of middleware
|
|
- `config.lazy` - Lazy load component
|
|
|
|
### router.guard(name, guardFn)
|
|
|
|
Register a route guard.
|
|
|
|
**Parameters**:
|
|
- `name` - Guard name
|
|
- `guardFn` - 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 path
|
|
- `options.container` - Container element
|
|
- `options.updateHistory` - Update browser history
|
|
|
|
**Returns**: `Promise<boolean>`
|
|
|
|
---
|
|
|
|
## Route Guards
|
|
|
|
### Authentication Guard
|
|
|
|
```javascript
|
|
router.guard('auth', async (to, from) => {
|
|
if (!isAuthenticated()) {
|
|
return '/login';
|
|
}
|
|
return true;
|
|
});
|
|
|
|
// Use in route
|
|
router.route('/dashboard', {
|
|
component: DashboardComponent,
|
|
guards: ['auth']
|
|
});
|
|
```
|
|
|
|
### Role Guard
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
```javascript
|
|
// 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
|
|
|
|
```javascript
|
|
router.use('loading'); // Shows loading indicator during navigation
|
|
```
|
|
|
|
### Scroll to Top Middleware
|
|
|
|
```javascript
|
|
router.use('scroll-to-top'); // Scrolls to top after navigation
|
|
```
|
|
|
|
---
|
|
|
|
## Lazy Route Loading
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
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
|
|
|
|
```javascript
|
|
router.route('/api-data', {
|
|
component: ApiDataComponent,
|
|
middleware: ['analytics', 'loading']
|
|
});
|
|
```
|
|
|
|
### Lazy Loading
|
|
|
|
```javascript
|
|
router.route('/heavy-page', {
|
|
component: () => import('./pages/HeavyPage.js'),
|
|
lazy: true,
|
|
guards: ['auth']
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
1. **Use Guards for Access Control** - Protect routes with guards
|
|
2. **Use Middleware for Cross-Cutting Concerns** - Analytics, loading, etc.
|
|
3. **Lazy Load Heavy Routes** - Improve initial load time
|
|
4. **Track Navigation** - Use analytics to understand user behavior
|
|
5. **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](analytics.md) →
|
|
|