Skip to content

Latest commit

ย 

History

551 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

logo

mobx-route

NPM version build status npm download bundle size

๐Ÿš€ Simple and lightweight typed MobX router ๐Ÿš€ Uses path-to-regexp power for path matching


Quick Start

import { createRoute } from "mobx-route";

const userDetails = createRoute("/users/:id");

// Path params are required โ€” TypeScript enforces it
await userDetails.open({ id: 1 });

userDetails.isOpened; // true
userDetails.params;   // { id: "1" } โ€” fully typed

โœจ Features

๐Ÿ”— Nested Routes with .extend()

Build route trees naturally โ€” no config arrays, no <Routes> wrappers:

const users = createRoute("/users");
const userDetails = users.extend("/:userId");
const userPhotos = userDetails.extend("/photos");

// Path is auto-concatenated: /users/:userId/photos
await userPhotos.open({ userId: 42 });
// โ†’ /users/42/photos

users.isOpened;        // true (parent is open too)
users.hasOpenedChildren; // true

๐Ÿ›ก๏ธ Route Guards & Redirects

Protect routes with beforeOpen โ€” cancel navigation or redirect:

const dashboard = createRoute("/dashboard", {
  beforeOpen: async () => {
    if (!await isAuthenticated()) {
      return { url: "/login", replace: true }; // redirect
    }
    // return undefined โ†’ proceed
  },
  checkOpened: () => currentUser.isAuthorized, // reactive predicate
});

๐Ÿ”ฎ Virtual Routes for Modals & Drawers

Same .open() / .close() / .isOpened API โ€” but no URL involved:

const authModal = createVirtualRoute({
  checkOpened: (route) => route.query.data.modal === "auth",
  open: (_, route) => route.query.update({ modal: "auth" }),
  close: (route) => route.query.update({ modal: undefined }),
  beforeClose: () => !hasUnsavedChanges, // prevent closing
});

authModal.isOpened;  // reactive โ€” auto-updates from query
authModal.isClosing; // for exit animations

๐ŸŽฏ Typed Query Params

const search = createRoute<
  "/search",
  {},
  {},
  { q: string; page?: number; sort?: "asc" | "desc" }
>("/search");

// TQueryParams types the INPUT โ€” what you pass to open()
await search.open({}, { query: { q: "mobx", page: 1 } });

// query.data is always Record<string, string> at runtime (values come from URL)
search.query.data.q;    // string
search.query.data.page; // string | undefined โ€” use Number() or QueryParam for typed access

๐Ÿ”„ update() for In-Place Changes

Replace params without polluting browser history:

await userRoute.open({ userId: 1 }, { query: { tab: "profile" } });
await userRoute.update({ userId: 2 });
// โ†’ /users/2?tab=profile (replace: true, mergeQuery: true by default)

๐Ÿงฉ React Integration

import { RouteView, RouteViewGroup, Link } from "mobx-route/react";

// Declarative route rendering
<RouteView route={userRoute} view={UserPage} fallback={<Loading />} />

// Route switching with fallback
<RouteViewGroup otherwise={notFoundRoute}>
  <RouteView route={homeRoute} view={HomePage} />
  <RouteView route={userRoute} view={UserPage} />
  <div>Not found</div>
</RouteViewGroup>

// Type-safe links
<Link to={userRoute} params={{ userId: 42 }}>Profile</Link>

๐Ÿง  View Model Integration

import { RouteViewModel } from "mobx-route/view-model";

class UserPageVM extends RouteViewModel<typeof userRoute> {
  route = userRoute;
  // payload, pathParams, query, isMounted โ€” all built-in
}

๐ŸŒ Optional Path Segments & Wildcards

// Optional segment
const route = createRoute("/users{/:tab}");
route.open();          // โ†’ /users
route.open({ tab: 1 }); // โ†’ /users/1

// Wildcard/rest params
const docs = createRoute("/docs/*rest");
docs.open({ rest: ["api", "v2", "auth"] }); // โ†’ /docs/api/v2/auth

๐Ÿ“ฆ Tree-Shakeable Subpath Exports

Only pay for what you use:

import { createRoute } from "mobx-route";              // core only
import { RouteView, Link } from "mobx-route/react";    // + React
import { RouteViewModel } from "mobx-route/view-model"; // + VM

Installation

npm install mobx-route
# or
pnpm add mobx-route
# or
yarn add mobx-route

Peer dependencies (React integration is optional):

npm install mobx
# For React:
npm install mobx-react-lite react react-dom

Contribution Guide

Want to contribute? Follow this guide


License

MIT

About

๐Ÿš€ Simple and lightweight typed MobX router ๐Ÿš€

Resources

Contributing

Stars

6 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages