Routing & Guards
Weblisk uses the browser's native navigation (MPA links) rather than client-side routing. But you can add guards and hooks to control navigation behavior.
Route Guards
Protect routes with before/after navigation hooks:
import { beforeNavigate, afterNavigate, installGuards } from 'weblisk/nav/guard.js'; // Install the navigation interceptor installGuards(); // Block unauthenticated access beforeNavigate((to, from) => { if (to.startsWith('/dashboard') && !isLoggedIn()) { return '/login'; // Redirect } return true; // Allow }); // Warn about unsaved changes beforeNavigate((to, from) => { if (hasUnsavedChanges()) { return confirm('You have unsaved changes. Leave?'); } }); // Track page views afterNavigate((to) => { analytics.track('pageview', { path: to }); });
Guard Return Values
| Return | Effect |
|--------|--------|
| true | Allow navigation |
| false | Block navigation |
| string | Redirect to that URL |
| Promise | Awaited, then same rules apply |
Scroll Restoration
Save and restore scroll positions across navigations:
import { installScroll } from 'weblisk/nav/scroll.js'; installScroll({ offset: 80, // Account for sticky header savePositions: true, // Remember scroll position per page });
Manual Control
import { saveScroll, restoreScroll, scrollToAnchor } from 'weblisk/nav/scroll.js'; saveScroll('/products'); restoreScroll('/products', 'smooth'); scrollToAnchor('#pricing', 80); // 80px header offset
View Transitions
Smooth page transitions using the View Transitions API:
import { navigate, transitionNames } from 'weblisk/nav/transition.js'; // Navigate with a transition await navigate('/about'); // Navigate with a custom transition type await navigate('/products', { types: ['slide-left'] }); // Assign transition names for cross-page element matching transitionNames({ '.hero-image': 'hero', '.page-title': 'title', });
Falls back to a CSS crossfade on browsers without View Transitions support.
Navigation Interceptor
Upgrade standard MPA link clicks into SPA-style content swaps without changing your HTML:
import { intercept } from 'weblisk/nav/router.js'; const router = intercept({ container: 'main', // Swap this element's content transition: true, // Use view transitions scroll: true, // Scroll to top after swap exclude: ['/api/'], // Skip these URL patterns onNavigate: (url) => console.log('Navigated to', url), }); // Cleanup router.destroy();
Uses the Navigation API where available, with click interception + popstate as a fallback. Links with target, download, data-no-intercept, or modifier keys are always left alone.