Skip to content

About

A simple router for MobX + React apps

Topics

Resources

Stars

505 stars

Watchers

19 watching

Forks

Repository files navigation

mobx-router

A simple router for MobX + React apps

Kitze Made by Kitze
kitze.io · X · YouTube


More projects by Kitze

pwn.watch logo
pwn.watch
Live security incidents: CVEs, patch status, fixed versions and advisories.
flavors.design logo
flavors.design
Copy-pasteable design flavors. Pick a vibe, hand the markdown to your agent.
gifs.so logo
gifs.so
Search, copy, and download reaction GIFs.
Shipper logo
Shipper
Changelog, roadmap, feature requests and tasks for every product you ship.
Kanso logo
Kanso
One keyboard-first app for your todos, habits, routines, planner and saved stuff.
HealthMaxx logo
HealthMaxx
One health log for everything you track: by hand, from wearables, or through your AI.
Zero To Shipped logo
Zero To Shipped
A full-stack starter kit for web and mobile apps.
Sotto logo
Sotto
Voice-to-text for macOS. Local AI, one-time purchase.
Tinkerer Club logo
Tinkerer Club
A private community for builders, self-hosters, and AI tinkerers.
Sizzy logo
Sizzy
The browser for web developers.
Supermac logo
Supermac
A macOS command center for everyday workflows.
DMX logo
DMX
A focused desktop client for X.

Support this project

Buy me a coffee   Sponsor on GitHub

Sponsors

Matte logo
Matte
3D mockups and screen recordings with pro-level video editing
Postiz logo
Postiz
Agentic social scheduler for GIFs!
ScreenshotOne logo
ScreenshotOne
The best screenshot API for developers and agents
ether.fi logo
ether.fi
a neobank with a built in ai-connector, build your own frontend to your finance with claude, chatgpt or your LLM of choice! Feedback always welcome!
OpenProse logo
OpenProse
Reliable, event-driven multiagent workflows — in Markdown.
OpenTweet logo
OpenTweet
Agentic X (Twitter) autopilot.
AppSumo logo
AppSumo
1M+ entrepreneurs use AppSumo to find the best deals on software for their business. One-time payments, lifetime access.
Team Spartan by CONFLICT logo
Team Spartan by CONFLICT
Know what matters. Get it fixed. Experience spans high-traffic consumer platforms, cloud infrastructure, and security — built under real operational pressure.
Browserless.io logo
Browserless.io
The web layer your agent runs on.
Strix logo
Strix
Hack yourself before the bad guys do. Open source (70k+ stars on Github)
Maple VC logo
Maple VC
We're 3 operators (digitalocean, uber, shopify) turned investors who write first checks into folks with ambition to build global businesses.
Rakazo logo
Rakazo
Open source Grok Bot
The Influencer AI logo
The Influencer AI
AI influencer generator: create a realistic influencer from traits or your photos, then make photos, talking videos and UGC ads with the same face every time.
Pluginboard logo
Pluginboard
Find the right plugins for your AI agents. Plugins, skills and step-by-step recipes for Claude, ChatGPT, Grokbot, Muse, Gemini and more.
file.cafe logo
file.cafe
Free, instant file sharing.
LinkDR logo
LinkDR
Link building that works: real backlinks from hundreds of high-DR sites, done for you or self-serve.
Outmano logo
Outmano
AI agents that watch your competitors so you don't have to
Mixpost logo
Mixpost
Self-hosted social media scheduler. Pay once.
Synteq logo
Synteq
The cloud, built for developers.
Kraken.io logo
Kraken.io
We optimize your images, to save you bandwidth, make your websites faster, make your customers less frustrated, and reduce your CDN costs.
Open Source Alternatives logo
Open Source Alternatives
Best Open Source Alternatives to Paid Software. Type anything and It answers with the right open source alternatives.
WATASU logo
WATASU
Hosting for your vibe-coded app
Your product here
Reach developers in every kitze repo.



🙋‍♂️ Made by @thekitze

Other projects:

  • 🏫 React Academy - Interactive React and GraphQL workshops
  • 💌 Twizzy - A standalone app for Twitter DM
  • 💻 Sizzy - A tool for testing responsive design on multiple devices at once
  • 🤖 JSUI - A powerful UI toolkit for managing JavaScript apps

Zero To Shipped


〽️ MobX Router

Example usage

Inspiration

📖 How to decouple state and UI - a.k.a. you don’t need componentWillMount

Features

  • Decoupled state from UI
  • Central route configuration
  • URL changes are triggering changes directly in the store, and vice-versa
  • No need to use component lifecycle methods like componentWillMount to fetch data or trigger a side effect in the store
  • Supported callbacks for the routes are: beforeEnter, onEnter, beforeExit, onExit. All of the callbacks receive route, params, store, and queryParams as parameters. If the beforeExit or beforeEnter methods return false the navigation action will be prevented.
  • The current URL params and query params are accessible directly in the store store.router.params / store.router.queryParams so basically they're available everywhere without any additional wrapping or HOC.
  • Navigating to another route happens by calling the goTo method on the router store, and the changes in the url are reflected automatically. So for example you can call router.goTo(routes.book, {id:5, page:3}) and after the change is made in the store, the URL change will follow. You never directly manipulate the URL or the history object.
  • <Link> component which also populates the href attribute and works with middle click or cmd/ctrl + click
  • Typescript support (Converted to typescript by thdk)
  • Hash-based routing (using paths like /#/foo/bar) support

Implementation

import React, {createContext} from 'react';
import ReactDOM from 'react-dom';

import {MobxRouter, RouterStore, startRouter} from 'mobx-router';
import routes from 'config/routes';

//example mobx store
export class AppStore {
    title = 'MobX Router Example App',
    user = null
}

export class RootStore {
    public router: RouterStore<RootStore>;
    public app: AppStore;

    constructor() {
        this.router = new RouterStore<RootStore>(this);
        this.app = new AppStore();
    }
}

const store = new RootStore();

// Use React context to make your store available in your application
const StoreContext = createContext({});
const StoreProvider = StoreContext.Provider;

startRouter(routes, store);

ReactDOM.render(
  <StoreProvider value={store}>
  	<MobxRouter store={store}/>
  </StoreProvider>, document.getElementById('root')
)

Example config

/config/routes.js

import React from 'react';

//models
import {Route} from 'mobx-router';

//components
import Home from 'components/Home';
import Document from 'components/Document';
import Gallery from 'components/Gallery';
import Book from 'components/Book';
import UserProfile from 'components/UserProfile';

const routes = {
  home: new Route({
    path: '/',
    component: <Home/>
  }),
  userProfile: new Route({
    path: '/profile/:username/:tab',
    component: <UserProfile/>,
    onEnter: () => {
      console.log('entering user profile!');
    },
    beforeExit: () => {
      console.log('exiting user profile!');
    },
    onParamsChange: (route, params, store) => {
      console.log('params changed to', params);
    }
  }),
  gallery: new Route({
    path: '/gallery',
    component: <Gallery/>,
    onEnter: (route, params, store, queryParams) => {
    	store.gallery.fetchImages();
    	console.log('current query params are -> ', queryParams);
    },
    beforeExit: () => {
      const result = confirm('Are you sure you want to leave the gallery?');
      return result;
    }
  }),
  document: new Route({
    path: '/document/:id',
    component: <Document/>,
    beforeEnter: (route, params, store) => {
      const userIsLoggedIn = store.app.user;
      if (!userIsLoggedIn) {
        alert('Only logged in users can enter this route!');
        return false;
      }
    },
    onEnter: (route, params) => {
      console.log(`entering document with params`, params);
    }
  }),
  book: new Route({
    path: '/book/:id/page/:page',
    component: <Book/>,
    onEnter: (route, params, store) => {
      console.log(`entering book with params`, params);
      store.app.setTitle(route.title);
    }
  })
};
export default routes;

Custom director configuration

mobx-router uses director behind the scenes. mobx-router exposes the director config object for you to pass your own configuration to director.

To do this you must pass a DirectorConfig object as third argument of startRouter method.

Hash based Routing | html5history

If you disable html5history option, mobx will fallback to hash based routing.

startRouter(
  routes, 
  store, 
  {
    // https://github.com/flatiron/director#configuration
    html5history: false,
  }
);

Not found (404) route | notfound

You can pass a function to notfound which will be called when you don't have any matching route for the current path.

startRouter(
  routes, 
  store, 
  {
    // https://github.com/flatiron/director#configuration
    notfound: () => store.router.goTo(YOUR_NOT_FOUND_ROUTE),
  }
);

More projects by Kitze

Apps & tools

Perkz
Sell and manage access to private GitHub repositories.
JustWrite
Distraction-free writing sprints for macOS, with time or word-count goals.
Releaseflow
App updates and downloads.
Passlock
A macOS password manager with time locks and unlock challenges.

Open source

Skillbox
A self-hosted, versioned skills library for AI agents.
Unclutter
Remove page clutter with AI-powered, reusable browser rules.
PageGrade
Grade page clarity, writing, and on-page SEO.
Council
Let your coding agents deliberate together before making a plan.
CodexMaxx
Manage Codex accounts, usage, and active sessions on macOS.
React Hanger
A collection of useful React hooks.
React Genie
Animate React elements as they enter the viewport.
MobX Router
A simple router for MobX and React apps.

All projects · GitHub · Follow on X · YouTube

About

A simple router for MobX + React apps

Topics

Resources

Stars

505 stars

Watchers

19 watching

Forks

Releases

Packages

Used by

Contributors

Languages