.agents/skills/client-side-routing/SKILL.md
How to add routes without remounting the app shell. Use when adding a new route, fixing agent sidebar reloads on navigation, or choosing between `root.tsx` layout and pathless `_app.tsx` layout patterns.
npx skillsauth add BuilderIO/agent-native client-side-routingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
All templates are single-page apps using React Router. Navigation must not remount the app shell. The agent sidebar, document tree, and any other persistent chrome must survive route changes.
If the shell unmounts on every navigation, the agent chat reconnects/reloads, destroying in-progress work and hammering the backend.
The app shell (AgentSidebar + any top-level navigation) must be mounted ONCE, above the <Outlet />. Never wrap each page in its own <AppLayout> / <Layout>. React sees a different component at the outlet position on each nav and unmounts the entire subtree.
Mount <AppLayout> in root.tsx around <Outlet />:
// app/root.tsx
<AppLayout>
<Outlet />
</AppLayout>
Use a React Router pathless layout route:
app/routes/
_app.tsx # renders <AppLayout><Outlet /></AppLayout>
_app._index.tsx # / → under AppLayout
_app.settings.tsx # /settings → under AppLayout
_app.team.tsx # /team → under AppLayout
book.$slug.tsx # /book/:slug → no layout (public)
f.$.tsx # /f/* → no layout (public form filler)
The _ prefix on _app.tsx makes it a pathless parent — it contributes the layout but no URL segment. Route files prefixed with _app. nest under it and share the layout instance across navigations.
// ❌ BAD — each route wraps its own Layout, causing full remount on every nav
export default function Settings() {
return (
<AppLayout>
<SettingsContent />
</AppLayout>
);
}
If a page needs per-route data (e.g. sidebar highlighting the active document), derive it inside the layout from useParams() / useLocation() — don't pass it as a prop through every route file.
root.tsx): just render page content — nothing else._app.tsx): name the file _app.<segment>.tsx for authed routes, or bare <segment>.tsx for public routes.adding-a-feature — The four-area checklist referencing route layout patternscontext-awareness — Navigation state written on every route changetools
Public booking flow — the state machine, animations, and URL/app-state sync.
tools
Trigger-based automations — reminders, follow-ups, webhooks — across the booking lifecycle.
tools
Team event types, round-robin assignment, collective bookings, host weights, and no-show calibration.
development
The pure `computeAvailableSlots` function — inputs, outputs, invariants, and debugging guide.