Project 13, Modern UI
Client-side Router
Links change the page without a reload, the back button works, and every page has its own URL. All of it runs on about 60 lines of router code.
- Main API
- Navigation API
- Fallback
- History API
- Dependencies
- None
- Your browser
- Checking
A tiny app with routes
How it works
- Catch navigationsThe navigate event fires for link clicks, form submits and back or forward. The router checks if it can handle the URL.
- Interceptevent.intercept() stops the full page load and runs the route handler instead. The URL still updates.
- RenderThe matching route renders into the page. If the user clicks again quickly, the signal aborts the old load.
navigation.addEventListener("navigate", (event) => {
const url = new URL(event.destination.url);
if (!event.canIntercept || url.origin !== location.origin) return;
event.intercept({
async handler() {
const page = await loadRoute(url, { signal: event.signal });
outlet.replaceChildren(page); // URL already updated
},
});
});