Route
Class for creating path based route.
Routes are self-contained entities and do not require binding to a router.
You can track their open state using the isOpened property, and also "open" the route using the open() method.
Constructor
createRoute(
path: TPath,
config?: RouteConfiguration<TParentRoute>,
)
new Route( // class form
path: TPath,
config?: RouteConfiguration<TParentRoute>,
)Basic example
const users = createRoute('/users');
const userDetails = users.extend('/:userId');
const userPhotos = userDetails.extend('/photos');
await userPhotos.open({ userId: 1 });
users.isOpened; // true
userDetails.isOpened; // true
userPhotos.isOpened; // true;
location.pathname; // /users/1/photosRoute path
The route path is built using the path-to-regexp library. The path itself is specified as the first parameter when creating an instance of the Route class.
So you can use all power of this library with TypeScript support out-of-box
const route = createRoute('/*segment');
route.open({
segment: [1,2,3]
})Methods and properties
open()
Navigates to this route.
First argument can be required based on path declaration (first argument)
API Signature
open(params?, { query?, replace?, state?, mergeQuery? }): Promise<void>
open(params?, replace?, query?): Promise<void>More about mergeQuery you can read here
Examples:
const stars = createRoute('/stars');
await stars.open();
location.pathname; // /starsconst starDetails = createRoute('/stars/:starId');
await starDetails.open({ starId: 1 }, {
query: { bar: 'baz' }
});
const starsWithMeta = createRoute('/stars{/:meta}');
await starsWithMeta.open();
await starsWithMeta.open({ meta: 1 }, {
query: { foo: 'bar' },
});confirmOpening() protected
Route opening pipeline hook that is called by open() and internal path-match synchronization. Use it when you need custom side effects around route opening.
API Signature
protected confirmOpening(
trx: NavigationTrx<TInputParams>,
): Promise<true | undefined>trx is navigation transaction object:
url: target URLparams: input path params passed toopen(...)query: query params for the target URLstate: history state payloadreplace: usehistory.replaceinstead ofhistory.pushpreferSkipHistoryUpdate: internal flag to skip history update
If opening is rejected (for example, by beforeOpen) this method can return undefined. For inherited implementation, true means opening was confirmed.
Example:
class AnalyticsRoute<TPath extends string> extends Route<TPath> {
protected async confirmOpening(
trx: NavigationTrx<InputPathParams<TPath>>,
): Promise<true | undefined> {
const result = await super.confirmOpening(trx);
if (result) {
this.trackEvent('Opened');
}
return result;
}
private trackEvent(name: string) {
console.log(name);
}
}confirmClosing() protected
Route closing pipeline hook that is called when route path no longer matches current location. Use it to execute custom logic before afterClose is triggered.
API Signature
protected confirmClosing(): boolean | undefinedFor inherited implementation, returning truthy value confirms close and allows afterClose callback. Returning false or undefined can be used to skip close confirmation side effects.
Example:
class AnalyticsRoute<TPath extends string> extends Route<TPath> {
protected confirmClosing(): boolean | undefined {
const result = super.confirmClosing();
if (result) {
this.trackEvent('Closed');
}
return result;
}
private trackEvent(name: string) {
console.log(name);
}
}extend()
Allows to create child route based on this route with merging this route path and extending path.
Extending route from parent will ignore parameters:
index, params exact
Example:
const stars = createRoute('/stars');
const starDetails = stars.extends('/:starId');
starDetails.path; // '/stars/:starId'
await starDetails.open({ starId: 1 });
location.pathname; // /stars/1isIndex
Indicates if this route is an index route. Index routes activate when parent route path matches exactly.
Useful with groupping routes using groupRoutes
isHash
Indicates if this route is an hash based route.
Hash based routes work with only #hashstrings in browser address URL. This is useful when you want to create routes that only affect the hash part of the URL, such as for client-side routing or for creating routes that don't affect the server-side routing.
isOpened computed
Defines the "open" state for this route.
Returns true when current URL matches this route's path pattern.
Example:
const stars = createRoute('/stars');
stars.open();
stars.isOpened; // trueisOpening computed
Indicates if this route is currently in the process of opening.
Returns true when the route status is 'opening'.
params computed.struct
Current parsed path parameters. null if route isn't open.
Example:
const routeA = createRoute('/foo/bar/:baz');
location.href = '/foo/bar/1234';
routeA.params; // { baz: "1234" }parent observable.ref
Parent route
Example:
const routeA = createRoute('/a');
const routeB = routeA.extend('/b');
routeB.parent === routeA; // truepath computed
Matched path segment for current URL. null if route isn't open.
Example:
const routeA = createRoute('/foo/bar/:baz');
location.href = '/foo/bar/1234';
routeA.path; // '/foo/bar/1234'pathDeclaration
Route path pattern declaration (used for route matching, path-to-regexp)
Example:
const routeA = createRoute('/foo/bar/:baz');
location.href = '/foo/bar/1234';
routeA.pathDeclaration; // '/foo/bar/:baz'
routeA.path; // '/foo/bar/1234'hasOpenedChildren computed
true when any child route is currently opened.
Example:
const routeA = createRoute('/a');
const routeB = routeA.extend('/b');
const routeC = routeB.extend('/c');
history.pushState(null, '', '/a/b/c');
routeA.isOpened; // false
routeB.isOpened; // false;
routeC.isOpened; // true;
routeA.hasOpenedChildren; // true
routeB.hasOpenedChildren; // true
routeC.hasOpenedChildren; // falsechildren observable
Array of child routes. Automatically updated when using extend().
createUrl()
Generates full URL for route. Respects base URL and parent routes.
Third argument can be a boolean (same as mergeQuery) or object CreatedUrlOutputParams:
mergeQuery— whentrue, current query params from location are merged with the passedquery. See routeConfig#mergeQuery.omitQuery— whentrue, the generated URL has no search string; only the path (and hash if applicable) is returned.
Example:
const starDetails = createRoute('/stars/:starId');
starDetails.createUrl({ starId: 1 }, { bar: 1 }); // /stars/1?bar=1
starDetails.createUrl({ starId: 1 }, { baz: 2 }, true); // /stars/1?bar=1&baz=2
// path only, no query
starDetails.createUrl({ starId: 1 }, { bar: 1 }, { omitQuery: true }); // /stars/1More about mergeQuery you can read here
matchPath()
Checks whether provided path (or current location path) matches the route declaration. Returns parsed path data with params and matched path, or null if there is no match.
API Signature
matchPath(path?: string | null | undefined): ParsedPathData<TPath> | nullWhen path is omitted:
- for hash routes (
hash: true) it checkslocation.hash(without#) - for regular routes it checks
location.pathname
If route has baseUrl, matchPath() validates and strips it before matching.
Example:
const userRoute = createRoute('/users/:userId');
userRoute.matchPath('/users/42');
// { path: '/users/42', params: { userId: '42' } }
userRoute.matchPath('/posts/42');
// nulladdChildren() action
Manually add child routes. Prefer extend() for typical use cases.
removeChildren() action
Remove specified routes from children.
destroy()
Stops route reactions and cleans up internal subscriptions. Call this when route instance is no longer needed.
Configuration
Interface: RouteConfiguration
This is specific object used to detailed configure route.
Here is list of configuration properties which can be helpful:
abortSignal
AbortSignal used to destroy\cleanup route subscriptions
meta
Additional object which can contains meta information
const route = createRoute('/fruits/apples', {
meta: {
memes: true
}
});
console.log(route.meta?.memes); // trueexact
This property changes the route matching behavior to match only exact pathname provided as the first parameter.
This can be useful when building nested routes and you need to display sub routes within a certain parent route.
Default: false
Examples:
exact is false
const projectsRoute = createRoute('/projects', { exact: false });
history.push('/projects/123');
projectsRoute.isOpened; // trueexact is true
const projectsRoute = createRoute('/projects', { exact: true });
history.push('/projects/123');
projectsRoute.isOpened; // falseconst projectsRoute = createRoute('/projects');
const projectRoute = createRoute('/projects/:projectId');
history.push('/projects/123');
projectsRoute.isOpened; // true
projectRoute.isOpened; // trueparams()
A function that can be needed when it is necessary to cast parsed path parameters from route to a certain type.
const route = createRoute('/fruits/apples/:appleId', {
params: (params) => {
return {
appleId: params.appleId,
isIphone: params.appleId.includes('iphone')
}
}
});
route.open({ appleId: 'iphone' })
route.params?.isIphone; // trueAlso it can block "opened" statement for route if you will return false or null value from this function.
const route = createRoute('/numbers/:number', {
params: (params) => {
if (Number.isNaN(Number(params.number))) {
return null
}
return {
number: Number(params.number)
}
}
});
route.open({ number: 'string' })
route.isOpened; // falsecheckOpened()
Function allows you to add custom logic for "opened" statement
This check will only be called AFTER if this route is valid by pathname
const route = createRoute('/numbers/:number', {
checkOpened: (params) => {
return !Number.isNaN(Number(params.number))
}
});
route.open({ number: 'string' })
route.isOpened; // falsebeforeOpen
Event handler "before opening" a route, required for various checks before the route itself is opened.
With this handler, we can prevent the route from opening by returning false,
or override the navigation to another one by returning
{
url: string;
state?: any;
replace?: boolean;
}Example:
const route = createRoute('/foo/bar', {
beforeOpen: () => {
if (!auth.isAuth) {
return false;
}
}
})afterClose()
Calls after close route.
afterOpen()
Calls after open route.
createUrl()
Ability to customize path or query params before create route url.
Example:
const route = createRoute('/foo/bar/baz',{
createUrl: ({ params, query }) => {
return {
params,
query: {
...query,
openModal: true,
}
}
}
});
route.createUrl(); // /foo/bar/baz?openModal=true
await route.open(); // /foo/bar/baz?openModal=true