@akashjs/router API
createRouter(routes, options?)
Create a router instance with automatic scroll restoration.
function createRouter(routes: RouteConfig[], options?: RouterOptions): Router;
interface RouterOptions {
/** Enable automatic scroll restoration (default: true) */
scrollRestoration?: boolean;
}
interface Router {
navigate: NavigateFn;
route: () => ResolvedRoute | null;
dispose: () => void;
}Scroll restoration is enabled by default:
- Forward navigation scrolls to top (or to
#hashelement) - Back/Forward restores the saved scroll position
- Query-only changes preserve scroll position
- Opt out globally with
{ scrollRestoration: false } - Opt out per navigation with
navigate('/path', { scroll: false })
Hooks
useRoute()
Get reactive route information. Must be called inside a component within a router.
function useRoute(): RouteInfo;
interface RouteInfo {
path: () => string;
params: () => Record<string, string>;
query: () => Record<string, string>;
hash: () => string;
}useParams()
Shorthand for reactive route params.
function useParams(): () => Record<string, string>;useNavigate()
Get the navigate function.
function useNavigate(): NavigateFn;useSearchParams()
Reactive read/write access to URL query parameters.
function useSearchParams(): [
() => Record<string, string>,
(params: Record<string, string | null | undefined>, options?: SetSearchParamsOptions) => void,
];
interface SetSearchParamsOptions {
/** Replace all params instead of merging (default: false) */
replace?: boolean;
/** Push a new history entry instead of replacing (default: false) */
push?: boolean;
}const [searchParams, setSearchParams] = useSearchParams();
// Read (reactive)
const page = searchParams().page;
// Write — merges with existing params, uses replaceState by default
setSearchParams({ page: '2' });
// Remove a param
setSearchParams({ page: null });
// Replace ALL params
setSearchParams({ q: 'hello' }, { replace: true });
// Push to history (new back button entry)
setSearchParams({ page: '3' }, { push: true });useLoaderData()
Get loader data for the current route segment.
function useLoaderData<T>(): () => T | undefined;Components
Link
Declarative navigation component.
interface LinkProps {
to: string;
params?: Record<string, string>;
query?: Record<string, string>;
hash?: string;
replace?: boolean;
class?: string;
}Outlet
Renders the matched route component. Used in layout components.
Guards
composeGuards(...guards)
Compose multiple guards. First redirect wins.
function composeGuards(...guards: RouteGuard[]): RouteGuard;guardWith(check, redirectTo)
Create a guard from a boolean check.
function guardWith(
check: (ctx: GuardContext) => Promise<boolean> | boolean,
redirectTo: string,
): RouteGuard;Navigation Events
onBeforeNavigate(callback)
Register a callback that fires before navigation starts (before guards/loaders). Observational only — cannot block navigation. Auto-cleans up on component unmount.
function onBeforeNavigate(cb: NavigationEventCallback): () => void;onAfterNavigate(callback)
Register a callback that fires after navigation completes and DOM updates. Auto-cleans up on component unmount.
function onAfterNavigate(cb: NavigationEventCallback): () => void;NavigationEvent
interface NavigationEvent {
from: NavigationLocation;
to: NavigationLocation;
type: 'push' | 'replace' | 'pop';
}
interface NavigationLocation {
path: string;
params: Record<string, string>;
query: Record<string, string>;
hash: string;
}import { onBeforeNavigate, onAfterNavigate } from '@akashjs/router';
// Cancel in-flight requests when leaving a page
onBeforeNavigate(() => {
abortController.abort();
});
// Analytics + scroll to top on page changes
onAfterNavigate((event) => {
analytics.trackPageView(event.to.path);
if (event.from.path !== event.to.path) {
window.scrollTo(0, 0);
}
});Types
RouteConfig
interface RouteConfig {
path: string;
component: () => Promise<{ default: Component<any> }>;
layout?: () => Promise<{ default: Component<any> }>;
guard?: () => Promise<{ guard: RouteGuard }>;
loader?: () => Promise<{ loader: RouteLoader<any> }>;
children?: RouteConfig[];
}RouteGuard
type RouteGuard = (ctx: GuardContext) => Promise<NavigationResult | void> | void;RouteLoader
type RouteLoader<P> = (ctx: LoaderContext<P>) => Promise<unknown>;Middleware
defineMiddleware(fn)
Define a route middleware function.
function defineMiddleware(
fn: (ctx: MiddlewareContext) => Promise<NavigationResult | void> | NavigationResult | void,
): Middleware;runMiddleware(middlewares, ctx)
Execute an array of middleware in order.
function runMiddleware(middlewares: Middleware[], ctx: MiddlewareContext): Promise<NavigationResult | null>;composeMiddleware(...fns)
Compose multiple middleware functions into a single middleware.
function composeMiddleware(...fns: Middleware[]): Middleware;Route Transitions
canDeactivate(options)
Create a guard that prevents navigation when there are unsaved changes. Also registers a beforeunload handler for tab close / external navigation.
function canDeactivate(options: CanDeactivateOptions): RouteGuard;
interface CanDeactivateOptions {
/** Return true to allow navigation */
canLeave: () => boolean | Promise<boolean>;
/** Confirmation message (default: 'You have unsaved changes...') */
message?: string;
/** Use browser's native confirm dialog (default: true) */
useNativeConfirm?: boolean;
}The returned guard also exposes a .dispose() method to remove the beforeunload listener.
getRouteTransitionClasses(name?)
Return the enter/exit CSS class names for a route transition.
function getRouteTransitionClasses(name?: string): {
enterFrom: string;
enterActive: string;
enterTo: string;
exitFrom: string;
exitActive: string;
exitTo: string;
};Default name is 'route', producing classes like route-enter-from, route-exit-active, etc.
generateRouteTransitionCSS(name?, type?)
Generate CSS rules for common route transition types.
function generateRouteTransitionCSS(
name?: string, // default 'route'
type?: 'fade' | 'slide-left' | 'slide-right' | 'slide-up' | 'scale', // default 'fade'
): string;History Helpers
createHistory()
Create a reactive history manager wrapping the browser History API.
function createHistory(): HistoryManager;
interface HistoryManager {
location: Signal<HistoryLocation>;
push(url: string): void;
replace(url: string): void;
go(delta: number): void;
dispose(): void;
}
interface HistoryLocation {
pathname: string;
search: string;
hash: string;
}buildUrl(pathname, query?, hash?)
Construct a URL string from parts.
function buildUrl(
pathname: string,
query?: Record<string, string>,
hash?: string,
): string;parseQuery(search)
Parse a query string into a plain object.
function parseQuery(search: string): Record<string, string>;parseHash(hash)
Strip the leading # from a hash string.
function parseHash(hash: string): string;