@artischocke/router
v0.4.2-0
Published
A set of routing service methods and utilities for React applications
Downloads
6
Maintainers
Readme
Router
The library at the moment uses history package of version 4.10.1
, because it is assumed that the react-router-dom library version is 5
(I won't work with version 6
until it releases from beta state).
Install
npm install @artischocke/router
or, using Yarn:
yarn add @artischocke/router
Usage
Initial setup (using createRouterService
):
// router.ts
import { createRouterService } from '@artischocke/router';
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
createRouterService({
history,
});
export default history;
Router paths configuration:
// routerPaths.ts
import { getRouterNode } from '@artischocke/router';
const RouterPaths = {
indexPage: '/',
employerPage: getRouterNode('/employer', {
tariffsSection: '/tariffs',
vacanciesSection: '/vacancies',
}),
page404: '*',
};
// getRouterNode() returns an object with injected toString() and valueOf().
// This helps the methods like navigateTo() transform the passed object to string
// and receive expected value (like '/employer' in this case).
//
// However, if you use this 'toStringable' object elsewhere
// (where no '.toString()' transformations exist), you must
// call '.toString()' explicitly:
//
// console.log(RouterPaths.employerPage.toString());
// -> '/employer'
// console.log(RouterPaths.employerPage.tariffsSection);
// -> '/employer/tariffs'
export default RouterPaths;
Routes configuration:
// config.ts
import { lazy } from 'react';
import { getRouterPaths } from '@artischocke/router';
import RouterPaths from './routerPaths';
const IndexPage = lazy(() => import('../pages/indexPage'));
const EmployerPage = lazy(() => import('../pages/employerPage'));
const Page404 = lazy(() => import('../pages/page404'));
// You can provide your optional interfaces
// both for 'settings' entry (called 'RouteSettings')
// and for 'componentSettings' one (called 'ComponentSettings'):
interface RS {
exact: boolean;
isPrivate: boolean;
}
interface CS {
usePageWrapper: boolean;
useHeader: boolean;
}
// Later on, use the interfaces from above in 'getRouterPaths' call signature
// (they will help IDE to autocomplete entries in these objects):
const Routes = getRouterPaths<RS, CS>([
{
path: RouterPaths.indexPage,
component: IndexPage,
settings: { exact: true, isPrivate: false },
componentSettings: {
usePageWrapper: true,
useHeader: true,
},
},
{
path: RouterPaths.employerPage,
component: EmployerPage,
settings: { exact: false, isPrivate: false },
componentSettings: {
usePageWrapper: true,
useHeader: true,
},
subRoutes: [
{
path: RouterPaths.employerPage.tariffsSection,
component: /* another lazy loaded component */,
settings: { exact: true, isPrivate: true },
componentSettings: {
usePageWrapper: false,
useHeader: false,
},
},
{
path: RouterPaths.employerPage.vacanciesSection,
component: /* another lazy loaded component */,
settings: { exact: true, isPrivate: true },
componentSettings: {
usePageWrapper: false,
useHeader: false,
},
},
],
},
{
path: RouterPaths.page404,
component: Page404,
settings: { exact: false, isPrivate: false },
componentSettings: {
usePageWrapper: true,
useHeader: true,
},
},
]);
export default Routes;
// Root.tsx
import React from 'react';
import { Router, Route as ReactRouterRoute, Switch } from 'react-router-dom';
import history from './router';
import Routes from './config';
export default function Root() {
return (
<Router history={history}>
<Switch>
{props.routes.map((route) => {
const Route = route.settings.isPrivate
? PrivateRoute // use your own component with the logic you need
: ReactRouterRoute; // use default <Route /> component from 'react-router-dom'
return (
<Route
key={route.path}
path={route.path}
exact={route.settings.exact}
render={() => (
// use your own component to build the UI
<LayoutBuilder
component={route.component}
subRoutes={route.subRoutes}
componentSettings={route.componentSettings}
/>
)}
/>
);
})}
</Switch>
</Router>
);
}
Somewhere outside of React components, where you can't access react-router-dom
's hooks, and therefore are not allowed to use them:
// ComponentUtils.ts
import Router from '@artischocke/router';
export function handleRedirectToFancyPage(params: Record<string, string | number>) {
Router.navigateTo(
// pathname you want the Router redirect to
'/fancy-page/:fancyId',
// if you have some ':variable' in your pathname, then specify
// these parameters here, otherwise - pass null or empty object
{ fancyId: 123 },
// search query with either individual or multiple params;
// you can omit this parameter as well as the second one (or pass null instead)
{ searchQuery: 'foo', pages: ['1', '2'] },
);
// The result of the URL will be:
// '/fancy-page/123?searchQuery=foo&pages=1&pages=2'
}
API Reference
To-do list
- [ ] Write meaningful description
- [ ] Write API reference
- [x] Extend possible options in
Route.settings
andRoute.componentSettings
configurations - [x] Adding own route settings
- [x] Adding own component settings
- [ ] Custom variable pattern (not only
/:([A-z]+)/g
pattern)
Issues
If you find any bugs and other issues when using this library, please let me know about this. Report issues in the specified section.