Skip to main content
@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!

Single JSX Node
useCoreRouter Hook
NavLink Component
Multi-Layout Support

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

PropTypeRequired?DefaultComments
basePathstringno-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.
fallbackRouteRno-Route to use when no route is matched.
fallbackStateRecord<string, unknown>no-State to use when no route is matched.
onRouteChangeOnCoreReactRouteChange<R>no-Callback that is invoked when a route change has been processed.
onRouteRequestOnCoreReactRouteRequest<R>no-Callback that is invoked when a route change request is pending and ready to act on.
routesRecord<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.

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

PropTypeRequired?DefaultComments
anchorStyleCSSPropertiesno{ cursor: 'pointer' }A CSS style object that will be applied to the rendered anchor element.
childrenReact.ReactNodeyes-The content to render for the link.
hashstringno-The hash to be passed to the new route, which will trigger an auto-scroll after navigation on target element if one exists.
hrefstringno-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.
onClickReact.DispatchWithoutActiononly when route is not provided-Callback that is invoked when the link is clicked.
routeRyes, unless onClick is provided-The route to navigate to when link is clicked.
stateRecord<string, unknown>no-The state that gets passed to the rendered route component's props upon navigation.
staticContentReact.ReactNodeno-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.
staticStyleCSSPropertiesno-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.
addUnusedStateToQueryStringbooleannofalseIf true, any state that is not used to interpolate URL path params will be added to the query string.
discardOrphanedQueryStringPlaceholdersbooleannotrueIf true, any query string placeholders that are not used to interpolate the URL will be removed from path (i.e. discard orhpaned placeholders).
preEncodeQueryStringValuesForKeysstring[]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.

PropertyTypeRequired?DefaultComments
Layout({ children }: { children: JSX.Element | null }) => ReactElementno-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.)
componentJSX.Elementyes-The component that will be rendered when the route is navigated to.
hashScrollBehaviorScrollBehaviorno-Determines the scroll behavior when hash links are auto-srolled on route navigation.
pathstringyes-The route's path, relative to the app's base path.
addUnusedStateToQueryStringbooleannofalseIf true, any state that is not used to interpolate URL path params will be added to the query string.
preEncodeQueryStringValuesstring[]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.
removeUnusedQueryParamsbooleannotrueIf 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);
ParameterTypeRequired?DefaultComments
routeR or stringyes-Must be EITHER one of the routes that were created using the factory method generated via reactRoutesFactory OR the respective route's path.
stateRecord<string, unknown>no-The state to be passed to the new route.
hashstringno-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.

PropertyTypeRequired?DefaultComments
routeRyes-The route that was navigated to.
stateRecord<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.

PropertyTypeRequired?DefaultComments
newRouteRyes-The route that is being requested.
newStateRecord<string, unknown>no-The state that is being passed to the requested route.
oldRouteRno-The route of the last request that was approved.
oldStateRecord<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.

ScenarioReturn typeResulting behavior
Auto-approvevoid (i.e. do nothing)Request is auto-approved and proceeds with route change.
Explicit approval/cancellationPromise<boolean>Resolving true approves request and proceeds with route change; othwerwise, cancels route change.
Redirect to routePromise<R>Redirects to the provided route.
Redirect to route with statePromise<[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 hashPromise<[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 hashPromise<[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 pathPromise<string>Redirects to the route corresponding with the respective path.
Redirect using path with statePromise<[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 hashPromise<[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 hashPromise<[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.

PropTypeComments
activeHashstringThe hash value that was used when navigating to active route.
activeRouteRThe currently active route.
activeStateRecord<string, unknown>The state that was used when navigating to active route.
basePathstringThe base path that is currently configured for router.
navigateCoreReactRouterNavigateMethod 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;
ParameterTypeRequired?DefaultComments
payloadCoreRouteChangePayload<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;;
ParameterTypeRequired?DefaultComments
payloadCoreRouteRequestPayload<R>yes-Object containing information about the route change that is pending and ready to act on.