📝 Update Note: CSS mask animations (
mask-circleandmask-gradient) have been removed to simplify the codebase and reduce bundle size. The router now includes 7 standard animation types that work reliably across all browsers.
SeamlessRouter is an ultra-lightweight router for AJAX navigation that makes transitions between pages smooth without full page reloads.
🌐 Works with regular HTML files and CMS (MODX, WordPress, Bitrix, and others)
⚡ The easiest way to speed up your site — just 1 file, 0 configuration
🧹 Automatically cleans up junk — timers, event listeners, and old scripts
🔌 No dependencies — pure TypeScript/JavaScript
🎯 Full control — special attributes for managing script behavior
Key feature: the router works on any page, even if you access it directly via a link (for example, directly to /blog/).
Download the ready-to-use UMD version from the project root:
<script data-keep data-skip src="SeamlessRouter.umd.min.js"></script>File size: ~45.8KB (minified) | ~12.3KB gzipped
# Install dependencies (development only)
pnpm install
# Build all versions
pnpm build:all
# or just UMD version
pnpm build:umd
# or standard build (ES + UMD in dist/)
pnpm buildAfter building, you can use either:
- UMD version from root:
SeamlessRouter.umd.min.js(for direct download) - ES/UMD versions from dist/:
dist/SeamlessRouter.es.jsordist/SeamlessRouter.umd.js
Include on your site with the required attributes:
<!-- For UMD version from root -->
<script data-keep data-skip src="SeamlessRouter.umd.min.js"></script>
<!-- For ES version from dist -->
<script type="module" data-keep data-skip src="dist/SeamlessRouter.es.js"></script>Connection attributes:
data-keep— prevents the script from being removed during navigationdata-skip— prevents the script from being re-executed when new pages load
That's it! The router initializes automatically and starts working. No settings, init() calls, or configuration needed.
By default, all advanced features are enabled with optimal settings:
- Prefetching: Enabled with intelligent prediction
- Caching: 30MB LRU cache with important pages always cached
- Animations: 7 standard animation types (fade, slide, collapse, diagonal)
- Offline Mode: Service Worker with network-first strategy
The router automatically detects browser capabilities and provides appropriate fallbacks.
- Intercepts clicks on links (
<a href="...">) and buttons withdata-router-link - Loads a new page via
fetch()without reloading - Updates only the changed parts: title, meta tags, content
- Automatically cleans up scripts, timers, and listeners from the previous page
- If something goes wrong — automatic fallback to a regular page reload
The router provides special attributes for full control over script behavior:
<!-- data-keep: script is NOT removed when navigating to a new page -->
<script data-keep src="shared-library.js"></script>
<!-- data-skip: script is NOT executed when loading new pages -->
<script data-skip src="analytics.js"></script>
<!-- data-reload: script executes EVERY TIME, even if already cached -->
<script data-reload src="dynamic-widget.js"></script>
<!-- Combinations: do not remove AND do not execute -->
<script data-keep data-skip src="seamless-router.js"></script>For complete isolation and to prevent conflicts, all your scripts must be wrapped in an IIFE (Immediately Invoked Function Expression):
// ✅ CORRECT — script in IIFE format
(function() {
'use strict';
// All your page code here
let slider = new Slider();
window.myConfig = { /* ... */ }; // Even window.xxx is safe
})();
// ❌ INCORRECT — global variables
var slider = new Slider(); // Will cause conflicts between pages!- Isolation: variables from one page don't conflict with another
- Security: no memory leaks
- Simplicity: no need to worry about unique variable names
- Compatibility: if scripts are in IIFEs, the router works perfectly
The router does NOT require wrapping scripts in IIFEs automatically — that's the developer's responsibility.
SeamlessRouter/
├── src/
│ ├── core/
│ │ ├── Router/ # Navigation logic
│ │ ├── Sandbox/ # Sandbox for isolating scripts
│ │ └── utils/ # Helper functions
│ └── index.ts # Entry point
├── dist/
│ └── seamless-router.js # Ready-to-use file
├── examples/ # Usage examples
└── README.md
| Feature | SeamlessRouter | Other Routers |
|---|---|---|
| Size | ~5KB (after build) | 50-200KB |
| Dependencies | 0 | React/Vue/Angular |
| Configuration | Not required | JSON, objects, settings |
| Compatibility | Any HTML/CMS | SPA only |
| Initialization | Automatic | Manual init() call |
| Requirements | IIFE only | Architecture, build, framework |
- Add the router to all site pages with the correct attributes:
<html>
<head>
<title>My Site</title>
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/blog/">Blog</a>
<a href="/about/">About Us</a>
</nav>
<!-- Shared libraries needed on all pages -->
<script data-keep src="shared-library.js"></script>
<!-- The router itself - do not remove and do not re-run -->
<script data-keep data-skip src="seamless-router.js"></script>
<script>
// All page scripts in an IIFE
(function() {
'use strict';
console.log('This page works with SeamlessRouter!');
// This code doesn't conflict with code on other pages
let pageData = { title: 'Home' };
window.pageData = pageData; // Can write to window
})();
</script>
</body>
</html>- Create the page
/blog/index.html:
<!-- Widget that needs to be updated every time -->
<script data-reload src="comments-widget.js"></script>
<script>
// Blog also in an IIFE
(function() {
'use strict';
console.log('Blog loaded!');
// Can use the same variable names
let pageData = { title: 'Blog' }; // Doesn't conflict with home page
window.pageData = pageData;
})();
</script>- Enjoy fast transitions without reloading!
The router now includes four powerful advanced features:
- Hover prefetch: Loads pages when user hovers over links
- Touch prefetch: Works on mobile devices with touch events
- Intelligent prediction: Learns user navigation patterns
- Smart cancellation: Cancels prefetch if user moves away
// Enable/disable prefetching
router.getPrefetchManager().setEnabled(true);
// Get prefetch statistics
const stats = router.getIntelligentPrefetchStats();
console.log('Prefetch stats:', stats);- LRU strategy: Automatically removes least recently used pages
- Size limits: Configurable cache size (default: 30MB)
- Important pages: Always keeps critical pages cached
- Update checking: Checks for page updates via
last-modified
// Manage cache
const cacheManager = router.getCacheManager();
cacheManager.set('/page', htmlContent, headers);
const cached = cacheManager.get('/page');
// Get cache statistics
const stats = cacheManager.getStats();
console.log('Cache stats:', stats);- Service Worker: Caches pages for offline access
- Network-first strategy: Tries network, falls back to cache
- Offline indicator: Shows when device is offline
- Custom offline page: Beautiful fallback UI
// Check offline support
if (router.isOfflineModeSupported()) {
// Enable offline mode
router.setOfflineModeEnabled(true);
// Get Service Worker stats
const stats = await router.getServiceWorkerCacheStats();
console.log('Service Worker stats:', stats);
}- 7 animation types: fade, slide-left/right/up/down, collapse, diagonal
- Direction-aware: Different animations for forward/back navigation
- Accessibility: Respects
prefers-reduced-motion - Browser compatibility: Works in all modern browsers
- Customizable: Set default animation type and duration
// Control animations
router.setAnimationsEnabled(true);
router.setDefaultAnimationType('slide-left');
// Navigate with specific animation
router.navigateWithAnimation('/page', 'fade');
// Navigate without animation
router.navigateWithoutAnimation('/page');
// Get available animation types
const availableTypes = router.getAvailableAnimationTypes();
console.log('Available animations:', availableTypes);// Custom configuration
const router = new AdvancedRouter({
prefetch: {
enabled: true,
hoverDelay: 300,
mobilePrefetchLimit: 3
},
cache: {
enabled: true,
maxSizeMB: 50,
alwaysCache: ['/', '/about', '/contacts']
},
animations: {
enabled: true,
defaultDuration: 400,
respectReducedMotion: true
},
offline: {
enabled: true,
showOfflineIndicator: true
}
});A test script is included to verify all features work correctly:
- Open browser console on any page
- Run
runIntegrationTests()to test all features - Or test individual components:
testInitialization()- Check all managerstestCache()- Test cache functionalitytestPrefetch()- Test prefetch systemtestAnimations()- Test animation systemtestServiceWorker()- Test offline mode
PRs, improvements, and ideas are welcome!
Before a PR, make sure the project is built and tested.
The project is distributed under the MIT license.
Created with ❤️ for speed and smooth navigation.