🥱 Boring Router
Edit page
IntroductionRoute NotationParallel RoutesLifecycle HooksGet StartedExamples
References
中文文档

Introduction

Boring Router is a state-first router with light-weight route components. It manages observable (MobX) route states like route.$matched and route.$params, so the route components as well as your code can react to those states. Boring Router is written in TypeScript and it puts type safety in mind designing the API.

Check out examples here.

Route Notation

Boring Router uses schema-based, type-safe route notation. You don't need, and it is not recommended to write routes as strings with Boring Router.

const route = router.$route({
$children: {
workbench: {
$children: {
taskId: {
$match: /\d+/,
},
},
},
},
});
<Route match={route.workbench.taskId} component={WorkbenchTaskView} />
<Link to={route.workbench.taskId} params={{taskId: '123'}}>
Go to Task
</Link>

Route schema can be shared with Node.js backend and this makes route notations type-safe everywhere.

Parallel Routes

Views like sidebar, overlay can be easily routed with Boring Router parallel routes.

const route = router.$route({
/* primary route schema */
});
const sidebarRoute = router.$route('sidebar', {
/* sidebar route schema */
});

URL for parallel routes looks like /workbench?_sidebar=/notifications, and additional parallel routes work just like primary route in most cases.

Lifecycle Hooks

Boring Router supports before/will/after x enter/update/leave hooks.

route.workbench.$beforeEnter(async next => {
let {referrer} = next.$params;
if (await testReferrer(referrer)) {
return;
}
route.$replace();
});

To support full lifecycle hooks while keeping history navigation behavior right, Boring Router implements its own BrowserHistory with the ability to restore browser history stack according to a given snapshot.

Check out an example here.