Types
TypeScript types and interfaces exported by the router.
RouteComponentProps<TParams, TState>
Props type for route components without a loader. Includes navigation state management props.
import type { RouteComponentProps } from "@funstack/router";
type Props = RouteComponentProps<
{ userId: string }, // TParams - path parameters
{ scrollPosition: number } // TState - navigation state type
>;
// Equivalent to:
type Props = {
params: { userId: string };
state: { scrollPosition: number } | undefined;
// Async state update via replace navigation
setState: (
state: { scrollPosition: number } |
((prev: { scrollPosition: number } | undefined) => { scrollPosition: number })
) => Promise<void>;
// Sync state update via updateCurrentEntry
setStateSync: (
state: { scrollPosition: number } |
((prev: { scrollPosition: number } | undefined) => { scrollPosition: number })
) => void;
// Async reset via replace navigation
resetState: () => Promise<void>;
// Sync reset via updateCurrentEntry
resetStateSync: () => void;
info: unknown; // Ephemeral navigation info
isPending: boolean; // Whether a navigation transition is pending
};
setState vs setStateSync:
setState - Async method that returns a Promise. Uses replace navigation internally, ensuring the state update goes through the full navigation cycle. Because it performs a navigation, it is wrapped in a React transition and may set isPending to true.setStateSync - Synchronous method that updates state immediately using navigation.updateCurrentEntry(). This is not a navigation, so it bypasses React transitions and will never set isPending to true.resetState - Async method that clears navigation state via replace navigation. Like setState, it goes through a React transition and may set isPending to true.resetStateSync - Clears navigation state synchronously. Like setStateSync, this bypasses React transitions and will never set isPending to true.
RouteComponentPropsWithData<TParams, TData, TState>
Props type for route components with a loader. Extends RouteComponentProps with a data prop.
import type { RouteComponentPropsWithData } from "@funstack/router";
type Props = RouteComponentPropsWithData<
{ userId: string }, // TParams - path parameters
User, // TData - loader return type
{ selectedTab: string } // TState - navigation state type
>;
// Equivalent to:
type Props = {
params: { userId: string };
data: User;
state: { selectedTab: string } | undefined;
setState: (state: ...) => Promise<void>; // async
setStateSync: (state: ...) => void; // sync
resetState: () => Promise<void>; // async
resetStateSync: () => void; // sync
info: unknown; // Ephemeral navigation info
isPending: boolean; // Whether a navigation transition is pending
};
PathParams<T>
Utility type that extracts parameter types from a path pattern string.
import type { PathParams } from "@funstack/router";
// PathParams<"/users/:userId"> = { userId: string }
// PathParams<"/users/:userId/posts/:postId"> = { userId: string; postId: string }
// PathParams<"/about"> = Record<string, never>
type MyParams = PathParams<"/users/:userId">;
// { userId: string }
TypefulOpaqueRouteDefinition<Id, Params, State, Data>
A route definition that carries type information. Created when using route() or routeState() with an id property. This enables type-safe access to route params, state, and data via hooks.
import { route, routeState } from "@funstack/router";
import type { TypefulOpaqueRouteDefinition } from "@funstack/router";
// Route with id gets TypefulOpaqueRouteDefinition type
const userRoute = route({
id: "user",
path: "/users/:userId",
loader: () => ({ name: "John" }),
component: UserPage,
});
// Type: TypefulOpaqueRouteDefinition<"user", { userId: string }, undefined, { name: string }>
// Route without id gets OpaqueRouteDefinition (no type info)
const aboutRoute = route({
path: "/about",
component: AboutPage,
});
// Type: OpaqueRouteDefinition
Type Extraction Utilities
Helper types to extract type information from TypefulOpaqueRouteDefinition. Useful for advanced type manipulation.
import type {
ExtractRouteId,
ExtractRouteParams,
ExtractRouteState,
ExtractRouteData,
} from "@funstack/router";
const userRoute = route({
id: "user",
path: "/users/:userId",
loader: () => ({ name: "John", age: 30 }),
component: UserPage,
});
type Id = ExtractRouteId<typeof userRoute>;
// "user"
type Params = ExtractRouteParams<typeof userRoute>;
// { userId: string }
type State = ExtractRouteState<typeof userRoute>;
// undefined
type Data = ExtractRouteData<typeof userRoute>;
// { name: string; age: number }
RouteComponentPropsOf<T>
Utility type that extracts the component props type from a route definition. Returns RouteComponentProps for routes without a loader, or RouteComponentPropsWithData for routes with a loader. This is useful for typing route components separately from the route definition.
import { route, routeState } from "@funstack/router";
import type { RouteComponentPropsOf } from "@funstack/router";
// Route without loader
const userRoute = route({
id: "user",
path: "/users/:userId",
component: UserPage,
});
type UserPageProps = RouteComponentPropsOf<typeof userRoute>;
// RouteComponentProps<{ userId: string }, undefined>
function UserPage({ params }: UserPageProps) {
return <h1>User: {params.userId}</h1>;
}
// Route with loader
const profileRoute = route({
id: "profile",
path: "/profile/:userId",
loader: () => ({ name: "John", age: 30 }),
component: ProfilePage,
});
type ProfilePageProps = RouteComponentPropsOf<typeof profileRoute>;
// RouteComponentPropsWithData<{ userId: string }, { name: string; age: number }, undefined>
// Route with state
type MyState = { tab: string };
const settingsRoute = routeState<MyState>()({
id: "settings",
path: "/settings",
component: SettingsPage,
});
type SettingsPageProps = RouteComponentPropsOf<typeof settingsRoute>;
// RouteComponentProps<Record<string, never>, MyState>
Note: This utility requires a route with an id property. Using it with a route without id will result in a type error.
RouteDefinition
The component field accepts two forms:
- Component reference (e.g.,
component: UserPage): Router automatically injects props (params, state, setState, setStateSync, resetState, resetStateSync, info, isPending, and data when a loader is defined). - JSX element (e.g.,
component: <UserPage />): Rendered as-is without router props injection. Useful for static components or when you want to pass custom props.
// Component reference: router injects props automatically
route({
path: "/users/:userId",
component: UserPage, // receives { params, state, setState, ... }
});
// JSX element: rendered as-is, no props injection
route({
path: "/about",
component: <AboutPage title="About Us" />, // custom props only
});
// With loader and state:
routeState<{ tab: string }>()({
path: "/users/:userId",
component: UserPage, // receives { data, params, state, ... }
loader: () => fetchUser(),
});
ActionArgs
Arguments passed to route action functions. The request carries the POST method and FormData body from the form submission.
interface ActionArgs<Params> {
params: Params;
request: Request; // method: "POST", body: FormData
signal: AbortSignal;
}
LoaderArgs
Arguments passed to route loader functions. The optional actionResult parameter contains the return value of the route's action when the loader runs after a form submission.
interface LoaderArgs<Params, ActionResult = undefined> {
params: Params;
request: Request;
signal: AbortSignal;
actionResult: ActionResult | undefined;
}
On normal navigations, actionResult is undefined. After a form submission, it contains the action's return value (awaited if the action is async).
Location
interface Location {
pathname: string;
search: string;
hash: string;
entryId: string | null; // NavigationHistoryEntry.id
entryKey: string | null; // NavigationHistoryEntry.key
}
entryId and entryKey expose the corresponding properties from the Navigation API's NavigationHistoryEntry. entryId is a unique identifier for the entry — a new id is assigned when the entry is replaced. entryKey represents the slot in the entry list and is stable across replacements. Both are null when the Navigation API is unavailable (e.g., in static fallback mode).
Warning: Do not render these values directly in DOM, as they are not available during SSR and will cause a hydration mismatch. They are best suited for use as a React key or in effects/callbacks.
NavigateOptions
interface NavigateOptions {
replace?: boolean;
state?: unknown;
info?: unknown; // Ephemeral, not persisted in history
}
Note: state is persisted in history and available across back/forward navigation. info is ephemeral and only available during the navigation that triggered it.