@spa-tools/core-router
React Reference
Building a React based SPA? If so, keep your routing lean and mean with this React take on the Core Router!
reactRoutesFactory()
The reactRoutesFactory<R>
function returns a factory method, which when called transforms route
definitions into a React routes object. The resulting routes object is what you use in your app whenever
you need to provide routes to a Core React Router or when you need to specify a route for navigation.
The generic R
type is used to define the shape of the route that will be created and must
extend the default CoreReactRoute
type.
Usage
import { CoreReactRoute, reactRoutesFactory } from '@spa-tools/core-router';
import { DashboardView, FinancialsView, LoginView, SignupView } from './views';
// here we define a default layout to use for our normal routes
function MyDefaultLayout({ children }) {
return (
<div>
<header>My App Header</header>
<main>{children}</main>
<footer>My App Footer</footer>
</div>
);
}
// here we define a layout that we want to use for our auth flow routes
function MyAuthLayout({ children }) {
return (
<div>
<header>Login or Sign-up</header>
<main>{children}</main>
</div>
);
}
// adding custom properties to your routes is as simple
// as creating an interface that extends CoreReactRoute
interface MyCustomRoute extends CoreReactRoute {
requiresAuth: boolean;
}
// to create your routes, first generate a route factory method
const createMyRoutes = reactRoutesFactory<MyCustomRoute>();
// next define and create all of your routes, which you'll
// typically export to use throughout your app
export const myRoutes = createMyRoutes({
dashboardRoute: {
Layout: MyDefaultLayout,
component: <DashboardView />,
path: '/',
requiresAuth: true,
},
financialsRoute: {
Layout: MyDefaultLayout,
component: <FinancialsView />,
path: '/financials',
requiresAuth: true,
},
loginRoute: {
Layout: MyAuthLayout,
component: <LoginView />,
path: '/login',
requiresAuth: false,
},
signupRoute: {
Layout: MyAuthLayout,
component: <SignupView />,
path: '/signup',
requiresAuth: false,
},
});
<CoreReactRouter />
The CoreReactRouter
component is the single JSX element that handles all of the view rendering for your SPA.
Usage
import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import { CoreReactRouter } from '@spa-tools/core-router';
ReactDOM.createRoot(document.getElementById('root')!).render(
<StrictMode>
<CoreReactRouter
basePath='/app'
fallbackRoute={myRoutes.dashboardRoute}
onRouteChange={(route, state) => {
console.log('Route changed to:', route, 'with state:', state);
}}
onRouteRequest={({ newRoute, newState }) => {
console.log('Route requested:', newRoute, 'with state:', newState);
// depending on what you return determines how the router proceeds
return Promise.resolve(true);
}}
routes={myRoutes}
/>
</StrictMode>
);
Props
Prop | Type | Required? | Default | Comments |
---|---|---|---|---|
basePath | string | no | - | Used to build the full URL for each route. An example of a base path is /app which would be used to build the full URL for a route with a path of /home as /app/home . |
fallbackRoute | R | no | - | Route to use when no route is matched. |
fallbackState | Record<string, unknown> | no | - | State to use when no route is matched. |
onRouteChange | OnCoreReactRouteChange<R> | no | - | Callback that is invoked when a route change has been processed. |
onRouteRequest | OnCoreReactRouteRequest<R> | no | - | Callback that is invoked when a route change request is pending and ready to act on. |
routes | Record<string, R> | yes | - | The routes are created using a factory method generated via reactRoutesFactory . |
useCoreRouter()
The useCoreRouter
hook is used to access the Core React Router instance from within a function component.
Usage
import { useCoreRouter } from '@spa-tools/core-router';
function MyComponent() {
const router = useCoreRouter();
return (
<button
onClick={() => {
router.navigate(myRoutes.dashboardRoute);
}}
>
Go to Dashboard
</button>
);
}
Returns
Returns a CoreRouterHook
object.
<NavLink />
The NavLink
component renders a bonafide link that navigates to a route.
Usage
import { NavLink } from '@spa-tools/core-router';
function MyDashboardLink() {
return <NavLink route={myRoutes.dashboardRoute}>Go to Dashboard</NavLink>;
}
Props
Prop | Type | Required? | Default | Comments |
---|---|---|---|---|
anchorStyle | CSSProperties | no | { cursor: 'pointer' } | A CSS style object that will be applied to the rendered anchor element. |
children | React.ReactNode | yes | - | The content to render for the link. |
hash | string | no | - | The hash to be passed to the new route, which will trigger an auto-scroll after navigation on target element if one exists. |
href | string | no | - | The href to be passed to the rendered anchor element when linking to an external address. The target property will be automatically set to _blank when href is set. |
onClick | React.DispatchWithoutAction | only when route is not provided | - | Callback that is invoked when the link is clicked. |
route | R | yes, unless onClick is provided | - | The route to navigate to when link is clicked. |
state | Record<string, unknown> | no | - | The state that gets passed to the rendered route component's props upon navigation. |
staticContent | React.ReactNode | no | - | The content to render for the link when it is in an active state. This can be used if you would rather take explicit control over how a link is rendered in the active/static state. If not provided, then the children will be used when the route is active. |
staticStyle | CSSProperties | no | - | A CSS style object that will be applied to the rendered link's div wrapper when the route is active. This can be used to ensure you get different styling for active/static links. |
addUnusedStateToQueryString | boolean | no | false | If true , any state that is not used to interpolate URL path params will be added to the query string. |
discardOrphanedQueryStringPlaceholders | boolean | no | true | If true , any query string placeholders that are not used to interpolate the URL will be removed from path (i.e. discard orhpaned placeholders). |
preEncodeQueryStringValuesForKeys | string[] | no | [] | The querystring values for all keys provided will be pre-encoded, which in effect applies double-encoding. Example for use is if you have to pass file paths in a querystring and the consuming service requires it to be double URI encoded. |
CoreReactRoute
CoreReactRoute
is the base type that all Core React Router routes must extend.
Property | Type | Required? | Default | Comments |
---|---|---|---|---|
Layout | ({ children }: { children: JSX.Element | null }) => ReactElement | no | - | React component that will be used to wrap the component of the respective route. Use this if you have one or more standardized layouts (e.g. Appbar, leftnav, main, footer, etc.) you want to use for your routes. This is set at the route level to support multiple layouts designs (e.g. one for auth flows, another for dashboards, and perhaps a default for all other views, etc.) |
component | JSX.Element | yes | - | The component that will be rendered when the route is navigated to. |
hashScrollBehavior | ScrollBehavior | no | - | Determines the scroll behavior when hash links are auto-srolled on route navigation. |
path | string | yes | - | The route's path, relative to the app's base path. |
addUnusedStateToQueryString | boolean | no | false | If true , any state that is not used to interpolate URL path params will be added to the query string. |
preEncodeQueryStringValues | string[] | no | [] | The querystring values for all keys provided will be pre-encoded, which in effect applies double-encoding. Example for use is if you have to pass file paths in a querystring and the consuming service requires it to be double URI encoded. |
removeUnusedQueryParams | boolean | no | true | If true , any query string placeholders that are not used to interpolate the URL will be removed from path (i.e. discarded). |
CoreReactRouterNavigate
The CoreReactRouterNavigate
is the signature for the navigate
method that is used to navigate to a new route.
navigate(route, state, hash);
Parameter | Type | Required? | Default | Comments |
---|---|---|---|---|
route | R or string | yes | - | Must be EITHER one of the routes that were created using the factory method generated via reactRoutesFactory OR the respective route's path. |
state | Record<string, unknown> | no | - | The state to be passed to the new route. |
hash | string | no | - | The hash to be passed to the new route, which if the target route component contains the respective hash ID, it will auto-scroll to the respective element. |
CoreRouteChangePayload
CoreRouteChangePayload<R>
is the object that is passed to the onRouteChange
callback when a route change has been processed.
Property | Type | Required? | Default | Comments |
---|---|---|---|---|
route | R | yes | - | The route that was navigated to. |
state | Record<string, unknown> | no | - | The state that was passed to the route. |
CoreRouteRequestPayload
CoreRouteRequestPayload<R>
is the object that is passed to the onRouteRequest
callback when a route change request is pending and ready to act on.
Property | Type | Required? | Default | Comments |
---|---|---|---|---|
newRoute | R | yes | - | The route that is being requested. |
newState | Record<string, unknown> | no | - | The state that is being passed to the requested route. |
oldRoute | R | no | - | The route of the last request that was approved. |
oldState | Record<string, unknown> | no | - | The state of the last request that was approved. |
CoreRouteResponse
CoreRouteResponse<R>
is the response that the consumer returns from within the onRouteRequest
callback when a route change request
is pending and ready to act on. This is used to determine how the Core Router should proceed with the route change request and thus is
the mechanisim by which consumers maintain absolute control over routing flow logic.
Scenario | Return type | Resulting behavior |
---|---|---|
Auto-approve | void (i.e. do nothing) | Request is auto-approved and proceeds with route change. |
Explicit approval/cancellation | Promise<boolean> | Resolving true approves request and proceeds with route change; othwerwise, cancels route change. |
Redirect to route | Promise<R> | Redirects to the provided route. |
Redirect to route with state | Promise<[R, Record<string, unknown>]> | Redirects to the route provided in tuple's first element while applying state provided in second element. |
Redirect to route with state and hash | Promise<[R, Record<string, unknown>, string]> | Redirects to the route provided in tuple's first element while applying state provided in second element and requests scroll to target location's element via hash provided in third element. |
Redirect to route with hash | Promise<[R, string]> | Redirects to the route provided in tuple's first element and requests scroll to target location's element via hash provided in second element. |
Redirect using path | Promise<string> | Redirects to the route corresponding with the respective path. |
Redirect using path with state | Promise<[string, Record<string, unknown>]> | Redirects to the route corresponding with the respective path in tuple's first elment while applying state provided in second element. |
Redirect using path with state and hash | Promise<[string, Record<string, unknown>], string> | Redirects to the route corresponding with the respective path in tuple's first element while applying state provided in second element and requests scroll to target location's element via hash provided in third element. |
Redirect using path and hash | Promise<[string, string]> | Redirects to the route corresponding with the respective path in tuple's first element and requests scroll to target location's element via hash provided in second element. |
CoreRouterHook
CoreRouterHook
is the object that is returned from the useCoreRouter
hook.
Prop | Type | Comments |
---|---|---|
activeHash | string | The hash value that was used when navigating to active route. |
activeRoute | R | The currently active route. |
activeState | Record<string, unknown> | The state that was used when navigating to active route. |
basePath | string | The base path that is currently configured for router. |
navigate | CoreReactRouterNavigate | Method used to navigate to a new route. |
OnCoreReactRouteChange
OnCoreReactRouteChange<R>
defines the signature for the callback that is invoked after a route change has been processed.
type OnCoreReactRouteChange<R> = (payload: CoreRouteChangePayload<R>) => void;
Parameter | Type | Required? | Default | Comments |
---|---|---|---|---|
payload | CoreRouteChangePayload<R> | yes | - | Object containing information about the route change that was just processed. |
OnCoreReactRouteRequest
OnCoreReactRouteRequest<R>
is the signature for the callback that is invoked when a route change request is pending and ready to act on.
(payload: CoreRouteRequestPayload<R>) => Promise<CoreRouteResponse<R>> | void;;
Parameter | Type | Required? | Default | Comments |
---|---|---|---|---|
payload | CoreRouteRequestPayload<R> | yes | - | Object containing information about the route change that is pending and ready to act on. |