@curi/router
About
The @curi/router
package provides functions for creating a single-page application's router.
Installation
UMD scripts script are also available through Unpkg. You can access the package's exports using window.Curi
.
API
prepareRoutes
The prepareRoutes
function takes an application's routes and route interactions and returns an object. The returned object will be passed to createRouter
.
prepareRoutes
creates a reusable routing object, which means that it can be reused on the server instead of recompiling it for every request.
Arguments
routes
An array of route objects.createRouter
The createRouter
function is used to create a router.
Arguments
history
A Hickory history function. The history guide provides more information on how to choose which history type is right for an application.
routes
An array of prepared route objects describing all valid routes in the application.
options
An optional object with additional properties that can be passed to the router.
sideEffects
An array of side effect objects.
external
Values that should be accessible to a route's resolve
function respond
functions.
Using external
allows you to access APIs, data, etc. without having to import it in the module where the routes are defined.
invisibleRedirects
When a response object has a redirect
property, Curi will automatically navigate to the location specified by the property.
If the invisibleRedirects
property is false
(the default), Curi will emit the redirect response (any observers will be called with the response).
If invisibleRedirects
is set to true
, Curi will skip emitting the redirect; this effectively makes the redirect invisible to the application.
invisibleRedirects
should always be false
for server-side rendering, otherwise the application will render content for the incorrect location.
Router
The router has a number of properties for you to use when rendering your application.
url
The url
method is used to generate a URL string.
Arguments
url
takes a single argument, an object with details about the location to navigate to and how to navigate.
name
The name of a route.
params
An object of any route params for the named route (and any of its ancestors that require params).
hash
The hash string of a location.
query
The query value of a location.
navigate
The navigate
method is used to navigate programmatically. It takes an object with the details of where and how to navigate.
Arguments
navigate
takes a single argument, an object with details about the location to navigate to and how to navigate.
url
The URL string of the location to navigate to.
state
Any serializable state to attach to the location.
method
How to navigate. "push"
appends the new location after the current one. "replace"
replaces the current location. "anchor"
is the default method and acts like clicking a link. This behavior is a mix of "push"
and "replace"
where the current location is replaced if the new location has the exact same URL.
finished & cancelled
finished
is a function to call once the navigation has finished.
cancelled
is a function to call if the navigation is superseded by another navigation.
These properties should only be provided when navigating to asynchronous routes. Synchronous routes navigate immediately, so there is no waiting time for the navigation.
once
Register a response handler that will only be called one time.
When a matched route is async (it has a resolve
function), a response will not be created until the function has resolved. once
is useful for delaying an application's initial render.
Arguments
Response Handler
A function that will be called once the router has generated a response. If the router has already generated a response, the function will be called immediately with the existing response. Otherwise, the function will be called once a new response is generated.
The function will be passed an object with three properties: the response
, a navigation
object, and the router
.
Options
initial
When true
(the default), the response handler will be called immediately if there is an existing response. When false
, the response handler will not be called until a new response is generated.
observe
Register a response handler that will be called every time a response is generated.
When a matched route is async (it has a resolve
function), a response will not be created until the function has resolved.
observe
returns a function, which can be called to stop observing.
Arguments
Response Handler
A function that will be called whenever a new response is generated. If a response already exists when the function is called, the response handler will be called immediately with the existing response.
Options
initial
When true
(the default), the response handler will be called immediately if there is an existing response. When false
, the response handler will not be called until a new response is generated.
cancel
With navigating to an asynchronous route, there is a time between when a navigation begins and when the route's asynchronous actions have finished, during which a user may decide to cancel the navigation.
In a multi-page application, the browser updates the refresh button to a stop button. There is no equivalent functionality for single-page applications, so Curi provides a cancel
function to roughly imitate the behavior.
cancel
takes an observer function that will be called when navigation starts and when the navigation is finished. When the navigation starts, the observer function will be called with a function to cancel the navigation. When the navigation finishes, the function will be called with undefined
.
Calling cancel
returns a function to stop observing.
Arguments
Cancel Handler
A function that will be called when an asynchronous navigation begins and ends.
When the navigation begins, the function will be passed a function that can be called to cancel the navigation.
When the navigation ends, the function will be passed undefined
.
Calling the cancel handler after the navigation has ended does nothing.
current
The current
method returns the current response
and navigation
objects.
route
The route
method is used to get the public data about a route. This is useful in conjuction with route interactions.
history
The route's history object.
external
The external
value that was passed through createRouter
's options.
announce
The announce
side effect is used to announce navigation to screen readers. The announcement is done using an ARIA live region.
The side effect will create an element with a aria-live
attribute and add it to the DOM. This element will be styled to not be displayed on screen (but not actually hidden) so that only screen readers detect it.
The announce
function takes a single argument, which is a function that receives the object emitted by the router and returns the string that should be set for the screen reader to read.
The DOM element's aria-live
attribute will be "assertive"
by default, but you can use the side-effect factory's second argument to pass an alternative (i.e. "polite"
).
scroll
The scroll
side effect will scroll the page after a navigation.
When Curi is running in a browser, it relies on the History API to change locations. Navigating using the History API does not trigger scrolling to the top of the page after navigation, so this side effect scrolls for you.
Pop navigation, such as clicking the browser's back and forward buttons, will rely on the browser to correctly restore the scroll position.
title
The title
side effect will set the document's title.
The function takes a single argument, which is a function that takes the object emitted by a router and returns the string to set as the title.
The recommended approach for determining a title is to have routes set their meta.title
property in their respond
method.
Route Objects
route.name
A string that will be used to identify a route. This must be unique for every route.
route.path
A string pattern describing what the route matches. path
strings should not have a leading slash.
A route's path
is used to check if it matches a location's pathname
. When the path
matches, the route is selected.
Path matching is done using regular expressions compiled by path-to-regexp
. A path can include parameters, which are dynamic variables that are parsed from a location's pathname
. For advanced path formatting, please read path-to-regexp
's documentaion.
route.resolve
The resolve
property is a function that returns a Promise. It is used to run asynchronous actions for a route prior to rendering.
A route with a resolve
function is asynchronous, while one with no resolve
functions is synchronous. You can read more about this in the sync or async guide.
Every time that a route with a resolve
function matches, the route's resolve
function will be called. Simple caching can be done with the once
function from @curi/helpers
, while more advanced caching is left to the user.
The function will be passed an object with the matched route properties: name
, params
, partials
, and location
.
The value returned by the resolve
function will be passed to the route's respond
function through its resolved
property. If there is an uncaught error, resolved
will be null
and the error
will be passed.
route.respond
A function for modifying the response object.
The object returned by a route's respond
function will be merged with the route's intrinsic match properties to create the response object.
Only valid properties will be merged onto the response; everything else will be ignored. The valid properties are:
Arguments
options
A respond
function is passed an object with a number of properties that can be useful for modifying the response.
match
An object with the intrinsic route properties of a response.
name
The name of the matched route.
params
Route parameters parsed from the location.
partials
The names of any ancestor routes of the matched route.
location
The location that was used to match the route.
key
A two number tuple. The first number is the location's place in the session array. The second number starts and zero and is incremented by replace
navigation ([1,0]
would be replaced by [1,1]
).
resolved
An object with the value returned by the route's resolve
function.
If a route isn't async, resolved
will be null
.
error
If the route has a resolve
function that throws an uncaught error, the error
property will be that error. Otherwise, the property will be null
.
Ideally, the resolve
function will always catch its errors, but error
serves as a safety check.
Return Value
body
Typically, the body
is a component (or components) that will be rendered.
meta
An object whose properties are metadata about the response. This may include the status of the response (200, 301, etc.), a title string for the document, or a description to be set as a page's <meta name="Description">
.
data
Anything you want it to be.
redirect
An object with the name
of the route to redirect to, params
(if required), and optional hash
, query
, and state
properties.
The other values are copied directly, but redirect
will be turned into a location object using the object's name
(and params
if required).
The redirect
property can also be used to specify a redirect to an external location. An external redirect object has only one property: exernalURL
.
Responses with an external redirect are always emitted, even when invisibleRedirects
is true
. The actual location changing is left to the application.
children
An optional array of route objects for creating nested routes.
Any child routes will be matched relative to their parent route's path
. This means that if a parent route's path
string is "one"
and a child route's path
string is "two"
, the child will match a location whose pathname is /one/two
.
params
When path-to-regexp
matches paths, all parameters are extracted as strings. The params
object is used to specify functions to transform the extracted value.
Properties of the route.params
object are the names of params to be parsed. The paired value should be a function that takes a string (the value from the pathname
) and returns a new value (transformed using the function you provide).
By default, each param is decoded using decodeURIComponent
. A param function can be used to leave the param in its encoded form or to parse an integer param into a number.
Unnamed params are referred to by their index in the path
.
pathOptions
An object for configuring how the path-to-regexp
handles the path
.
match
Properties for parsing the path
into a regular expression.
You can see the options and their default values in the path-to-regexp
documentation.
compile
For pathname generation, the options are passed through a compile
object. There is only one possible option, which is an encode
function for encoding params. The default encode
function encodes params using encodeURIComponent
.
extra
If you have any additional properties that you want attached to a route, use the extra
property. You will be able to use route.extra
in any custom route interactions.