Overview

animatedRouter is the same ordered matcher as Router, with exit → swap → enter transitions. Pass component (not view). Global enter / exit presets can be overridden per route.

It calls claimRouterOutlet("animatedRouter") — mounting both Router and animatedRouter (or two outlets) in one scope throws.

Router vs animatedRouter

API
Matching
Transitions
Router ordered first-match Instant swap — no enter/exit animation.
animatedRouter same matching Exit → swap → enter using presets (global + per-route).

Tiny animatedRouter (two routes)

Home ↔ About with fade presets. Do not also mount Router.

import { html, animatedRouter, animationPresets, useUtils, renderApp } from 'mates';

const Home = () => () => html`<p class="muted">Home</p>`;
const About = () => () => html`<p class="muted">About</p>`;

const App = () => {
const { navigateTo, pathAtom } = useUtils();
const outlet = animatedRouter(
[
{ path: '/', component: Home },
{ path: '/about', component: About },
],
{
enter: animationPresets.fadeIn(200),
exit: animationPresets.fadeOut(150),
},
);

return () => html`
<div class="m-col m-gap">
<nav class="tabs">
<button @click=${() => navigateTo('/')}>Home</button>
<button @click=${() => navigateTo('/about')}>About</button>
</nav>
<p class="hint">path=${pathAtom()}</p>
${outlet}
</div>
`;
};
renderApp(App, document.getElementById('app'));

Per-route enter/exit

Same two routes; About gets slower fade. Global options still apply to Home.

import { html, animatedRouter, animationPresets, useUtils, renderApp } from 'mates';

const Home = () => () => html`<p class="muted">Home</p>`;
const About = () => () => html`<p class="muted">About</p>`;

const App = () => {
const { navigateTo } = useUtils();
const outlet = animatedRouter(
[
{ path: '/', component: Home },
{
path: '/about',
component: About,
enter: animationPresets.fadeIn(400),
exit: animationPresets.fadeOut(300),
},
],
{ enter: animationPresets.fadeIn(150), exit: animationPresets.fadeOut(100) },
);

return () => html`
<div class="m-col m-gap">
<div class="m-flex m-items-center m-justify-center m-gap-sm">
<button @click=${() => navigateTo('/')}>Home</button>
<button class="btn-primary" @click=${() => navigateTo('/about')}>About</button>
</div>
${outlet}
</div>
`;
};
renderApp(App, document.getElementById('app'));