Overview

onNavigate(fn) subscribes to pathAtom from the router scope. Whenever the path changes (via navigateTo, back/forward, etc.), fn receives the new path string.

Use it for side effects — analytics, scroll-to-top, closing menus. Do not use it to read route params; use paramsAtom / useUtils() instead.

Navigation APIs

API
Role
Notes
onNavigate(fn) Side effects Callback on path change; may return cleanup.
pathAtom Reactive path Read/write current pathname.
paramsAtom Route params Matched dynamic segments — not via onNavigate.

onNavigate — react to route changes

onNavigate subscribes to pathAtom. Clicking a route calls navigateTo — the log is written from the onNavigate callback, not from the click handler.

import { html, atom, onNavigate, renderApp, useUtils } from 'mates';

const App = () => {
const { navigateTo, pathAtom } = useUtils();
const history = atom([]);

onNavigate((path) => {
history.set((prev) => [...prev.slice(-4), path]);
});

const routes = ['/', '/about', '/docs', '/settings'];

return () => html`
<div class="m-col m-gap">
<p class="muted">
onNavigate runs whenever pathAtom changes via navigateTo.
</p>
<div class="m-flex m-items-center m-justify-center m-gap-sm">
${routes.map((p) => html`
<button
class=${pathAtom() === p ? 'btn-primary' : 'btn-ghost'}
@click=${() => navigateTo(p)}
>${p}</button>
`)}
</div>
<p class="hint">path=${pathAtom()}</p>
<div class="card card-body">
<span class="overline">onNavigate log</span>
${history().length === 0
? html`<p class="hint m-t-5">Click a route to append a path.</p>`
: history().map((p) => html`<div class="mono">→ ${p}</div>`)}
</div>
</div>
`;
};
renderApp(App, document.getElementById('app'));