Navigated to /docs/core/routing

Routing and navigation

Navigate between typed file routes while preserving browser history, focus, scroll, and pending state.

Prefetch intentionally

Prefetch routes when intent is clear, such as pointer hover or focus on a high-probability destination. Prefetching resolves work without changing the URL or rendering the target page's pending component. Route status APIs let interface code show loading, prefetching, ready, or error states without duplicating the router state machine.

TS
tsimport { getRouteStatus, prefetchRoute } from "@tavojs/core/router";

export async function prepareReports() {
  await prefetchRoute("/reports");
  return getRouteStatus("/reports");
}

Subscribe and inspect responsibly

Auto Pages exposes synchronous route state and disposable subscriptions from @tavojs/core/router. Development inspection lives under @tavojs/core/dev, while tavo routes and tavo inspect route show the generated graph without adding application code.

  • Use getResolvedRoute and getRouteStatus for current resolution state.

  • Use subscribeAvailableRoutes and subscribeRouteStatus when interface state must react to route changes.

  • Run tavo routes, tavo inspect route <path> --json, or import getAutoPagesInspection from @tavojs/core/dev during development.

TS
tsimport {
  getAvailableRoutes,
  getCurrentPathname,
  subscribePathname
} from "@tavojs/core/router";

console.log(getCurrentPathname(), getAvailableRoutes());

const unsubscribe = subscribePathname((pathname) => {
  console.log("Route changed:", pathname);
});

// Call when this observer's owner is disposed.
unsubscribe();

File-router navigation API

Auto Pages discovers application routes from src/pages. Import its navigation and route-state APIs from @tavojs/core/router. Reads are synchronous; subscribe functions return an unsubscribe callback; prefetchRoute resolves route middleware and loaders without changing browser history.

  • Route status is idle, loading, prefetching, ready, redirecting, or error.

  • A page pending export is visible only during active client-side route resolution; prefetchRoute never renders it.

  • Without an active resolver, prefetchRoute leaves the route idle rather than throwing.

  • Pass an AbortSignal when hover, focus, or another owner should be able to cancel a prefetch.

  • Call every returned unsubscribe function when its component, controller, or external owner is disposed.

  • Import getAutoPagesInspection from @tavojs/core/dev for development inspection, or use tavo routes and tavo inspect route <path> --json.

TS
tsnavigate(to: string, options?: { replace?: boolean; scroll?: boolean }): void
prefetchRoute(pathname: string, options?: { signal?: AbortSignal }): Promise<void>
getCurrentPathname(): string
subscribePathname(listener: (pathname: string) => void): () => void
getAvailableRoutes(): PageRouteDefinition[]
subscribeAvailableRoutes(listener: (routes: PageRouteDefinition[]) => void): () => void
getResolvedRoute(pathname?: string)
getRouteStatus(pathname?: string): RouteStatus
subscribeRouteStatus(listener: (status: RouteStatus, all: RouteStatusState) => void, pathname?: string): () => void

Standalone router reference

The standalone router is intended for embedded or client-only route areas. Do not create a second top-level router inside a file-routed application.

  • RouterProvider can render explicit children or the matched route component.

  • After navigation it announces status, focuses data-tavo-route-focus, main, h1, or role=main, and restores scroll.

  • navigate is a no-op during server rendering. Router params are decoded strings.

TSX
tsxconst router = createRouter([
  { path: "/", component: Home },
  { path: "/teams/:id", component: Team }
]);

router.navigate("/teams/core", { replace: false, scroll: true });
router.getPathname();
router.match("/teams/core"); // { route, params: { id: "core" } }

<RouterProvider
  router={router}
  notFound={<NotFound />}
  busy={false}
  contentId="route-content"
/>

Look up exact public types

Follow linked API names to their canonical TypeScript declarations and package boundaries.