Router

A lightweight client-side router with dynamic parameters, wildcard routes, grouped prefixes, middleware pipelines, navigation guards, and full browser history integration.

Quick Start

Register routes, add optional middleware, then call Aura.init() to start listening for URL changes.

js
import Aura from 'aurajs';

// Define routes
Aura.route('/', (ctx) => {
  console.log('Home page');
});

Aura.route('/users/:id', (ctx) => {
  console.log('User:', ctx.params.id);
});

// Add middleware
Aura.middleware((ctx) => {
  console.log('Navigating to', ctx.path);
  return true;
});

// Start the app
Aura.init();

Types

RouteContext

Every route handler and middleware receives a RouteContext object.

PropertyTypeDescription
pathstringThe full matched path including query string.
paramsRecord<string, string>Dynamic route parameters (e.g. :id).
queryRecord<string, string>Parsed query-string key/value pairs.
namestring | undefinedOptional route name, if one was provided.

route() core

Register a route with a path pattern and a handler function. Supports dynamic segments (:param) and wildcard catch-all (/*).

Aura.route(path: string, handler: RouteHandler, name?: string): void
ParamTypeDescription
pathstringURL pattern. Use :param for dynamic segments, /* for catch-all.
handlerRouteHandlerCallback (ctx: RouteContext) => void | Promise<void> invoked when the path matches.
namestringOptional name used with urlFor() for reverse-routing.
js
// Static route
Aura.route('/about', (ctx) => {
  document.querySelector('#app').innerHTML = '<h1>About</h1>';
});

// Dynamic parameter
Aura.route('/posts/:slug', (ctx) => {
  console.log(ctx.params.slug);
});

// Named route
Aura.route('/users/:id', showUser, 'user-detail');

// Wildcard catch-all
Aura.route('/files/*', (ctx) => {
  console.log(ctx.params.wildcard); // everything after /files/
});

group() organization

Group multiple routes under a shared URL prefix. The callback receives a scoped router object with a route() method that automatically prepends the prefix.

Aura.group(prefix: string, fn: (r: { route: (path: string, handler: RouteHandler, name?: string) => void }) => void): void
ParamTypeDescription
prefixstringURL prefix prepended to every route in the group (e.g. /admin).
fnFunctionCallback that receives a scoped router { route } for registering sub-routes.
js
Aura.group('/admin', (r) => {
  // Registers /admin/dashboard
  r.route('/dashboard', (ctx) => {
    console.log('Admin dashboard');
  });

  // Registers /admin/users/:id
  r.route('/users/:id', (ctx) => {
    console.log('Admin user', ctx.params.id);
  }, 'admin-user');
});

Programmatically navigate to a path. Pushes a new entry onto the browser history stack. Respects the beforeLeave guard and runs all registered middleware before executing the route handler.

Aura.navigate(path: string): Promise<void>
ParamTypeDescription
pathstringThe target URL path (e.g. /users/42).
js
// Navigate with history push
await Aura.navigate('/dashboard');

// Navigate with query params
await Aura.navigate('/search?q=aura&page=1');

redirect() core

Navigate to a path without pushing a new browser history entry. Useful for post-login redirects or replacing the current page silently.

Aura.redirect(path: string): Promise<void>
ParamTypeDescription
pathstringThe target URL path to redirect to.
js
// Redirect without adding to history
await Aura.redirect('/login');

middleware() guard

Register a global middleware function. Middleware runs in registration order before every route handler. Return true to continue or false to abort navigation (sets page state to 'error').

Aura.middleware(fn: (ctx: RouteContext) => boolean | Promise<boolean>): void
ParamTypeDescription
fnMiddlewareFunction receiving a RouteContext. Return false to block navigation.
js
// Auth guard middleware
Aura.middleware((ctx) => {
  if (ctx.path.startsWith('/admin') && !isLoggedIn()) {
    Aura.redirect('/login');
    return false;
  }
  return true;
});

// Logging middleware
Aura.middleware((ctx) => {
  console.log(`[Router]`, ctx.path);
  return true;
});

beforeLeave() guard

Register a navigation guard that fires before leaving the current route. Only applies when using navigate(). Return false to cancel navigation (e.g. for unsaved-changes prompts).

Aura.beforeLeave(fn: (from: string, to: string) => boolean | Promise<boolean>): void
ParamTypeDescription
fnFunctionGuard receiving the current path (from) and the target path (to). Return false to cancel.
js
Aura.beforeLeave((from, to) => {
  if (hasUnsavedChanges) {
    return confirm('Discard unsaved changes?');
  }
  return true;
});

errorPage() error

Register a handler for unmatched routes (404 pages). Called when no registered route pattern matches the requested path.

Aura.errorPage(handler: (ctx: RouteContext) => void | Promise<void>): void
ParamTypeDescription
handlerRouteHandlerCallback invoked with a context whose params is empty and path is the unmatched URL.
js
Aura.errorPage((ctx) => {
  document.querySelector('#app').innerHTML = `
    <h1>404</h1>
    <p>Page not found: ${ctx.path}</p>
  `;
});

refresh() core

Re-run the handler for the current route without changing the URL or pushing history. Useful after data updates when you need to re-render the current page.

Aura.refresh(): Promise<void>

This method takes no parameters.

js
// Re-execute the current route handler
await Aura.refresh();

urlFor() utility

Generate a URL string from a named route. Replaces :param placeholders with the provided values. Returns null if no route with the given name exists.

Aura.urlFor(name: string, params?: Record<string, string>): string | null
ParamTypeDescription
namestringThe name assigned when the route was registered.
paramsRecord<string, string>Optional map of parameter names to values to interpolate into the path.
js
// Register a named route
Aura.route('/users/:id/posts/:postId', handler, 'user-post');

// Generate the URL
const url = Aura.urlFor('user-post', { id: '42', postId: '7' });
// => "/users/42/posts/7"

// Unknown name returns null
Aura.urlFor('nope'); // => null

back() utility

Navigate back one entry in the browser history. Equivalent to history.back().

Aura.back(): void

This method takes no parameters.

js
Aura.back();

forward() utility

Navigate forward one entry in the browser history. Equivalent to history.forward().

Aura.forward(): void

This method takes no parameters.

js
Aura.forward();

pageState getter

Read-only getter returning the current page lifecycle state. The router automatically transitions through these states during navigation.

Aura.pageState: 'idle' | 'loading' | 'loaded' | 'error'
ValueMeaning
'idle'No navigation has occurred yet.
'loading'A route handler is currently executing.
'loaded'The route handler completed successfully.
'error'The handler threw, middleware blocked, or no route matched (404).
js
if (Aura.pageState === 'loading') {
  showSpinner();
}

currentPath getter

Read-only getter returning the full path (including query string) of the most recently handled route.

Aura.currentPath: string
js
console.log(Aura.currentPath); // e.g. "/users/42?tab=posts"

Read-only getter returning a copy of the internal navigation history array. Each entry records the path, extracted params, and a timestamp.

Aura.navigationHistory: HistoryEntry[]

HistoryEntry

PropertyTypeDescription
pathstringThe full navigated path.
paramsRecord<string, string>Extracted route parameters.
timestampnumberUnix timestamp (ms) of when the navigation occurred.
js
const history = Aura.navigationHistory;
console.log('Pages visited:', history.length);
console.log('Last page:', history[history.length - 1].path);

Emitted Events

The router emits the following events via the Aura event bus. Subscribe with Aura.on().

EventPayloadDescription
route:changeRouteContextFired after a route handler completes successfully.
route:error{ path, error }Fired when a route handler throws an exception.
route:notFound{ path }Fired when no registered route matches the path (404).
route:stateChangePageStateFired whenever the page state transitions.
js
Aura.on('route:change', (ctx) => {
  console.log('Navigated to', ctx.path);
});

Aura.on('route:notFound', ({ path }) => {
  console.log('404:', path);
});