Skip to content

<Router /> (React adapter)

routekit ships a tiny optional React adapter: <Router />. It wraps the same createRouter() API but exposes it as a component, which is more familiar to teams already deep in React.

Import

import { Router } from 'routekit/react';

The routekit/react subpath is tree-shakable. Importing only Router and useRoute lands at roughly 2.4 KB post-min+gzip in a real React bundle.

Signature

type RouterProps<T extends RouteDefinition[]> = {
routes: T;
base?: string;
fallback?: ReactNode;
onNavigate?: (match: Match<T>) => void;
};
function Router<T>(props: RouterProps<T>): JSX.Element;

Props

PropTypeDefaultDescription
routesRouteDefinition[]Same shape as the bare API. Use as const.
basestring'/'Base path.
fallbackReactNodenullRendered while a route handler is resolving.
onNavigate(match) => voidOptional callback for analytics, logging, etc.

Example

import { Router, useRoute } from 'routekit/react';
const routes = [
{ path: '/', handler: () => import('./pages/Home') },
{ path: '/posts/:id', handler: () => import('./pages/Post') },
] as const;
export default function App() {
return (
<Router routes={routes} fallback={<Spinner />}>
<AppShell>
<Outlet />
</AppShell>
</Router>
);
}
// In Outlet:
function Outlet() {
const { match, Page } = useRoute();
if (!Page) return null;
return <Page params={match.params} />;
}

How it works

The component:

  1. Calls createRouter(routes, { base }) once on mount.
  2. Subscribes to navigate events and stores { match, Page } in React state via useState + useEffect.
  3. Provides them via Context to descendants reading useRoute().
  4. Renders fallback while a chunk is resolving.
  5. Tears down the router subscription on unmount.

There’s no magic. If you want to see the source it’s about 90 lines.

When to use the React adapter

  • You want JSX. Mounting <Router /> and reading useRoute() feels native to React apps.
  • You want <Suspense /> integration. The adapter handles the chunk-loading boundary so you don’t have to wire it manually.
  • You want React-DevTools-friendly route changes. Each navigation triggers a normal React state update; route changes show up cleanly in profiling.

When to skip it

  • You’re not using React. Use createRouter() directly.
  • Your bundle budget is brutal. ~600 bytes is small but non-zero.
  • You want to manage the lifecycle yourself. The bare API gives you cleanup callbacks, manual start()/stop(), etc. The adapter takes those choices away.

Caveats

  • The adapter doesn’t ship with a <Link> component. Use plain <a href="..."> — routekit intercepts clicks at the document level. See navigation.
  • useRoute() returns null on first render, before the initial route resolves. Always null-check.
  • The adapter is React-only. There’s no Vue / Solid / Preact adapter shipped — for those, write 30 lines yourself or use createRouter() directly with your framework’s lifecycle hooks.