Routing in web apps can be a subtle, but persistent source of bugs. You think you've updated every reference to a route you're changing, and BAM. You've caused a bug in some unrelated part of your app.
This gets worse when you need to add path parameters (/user/:id/edit) and search parameters (/auth?redirectPath=somewhere). Usually, this leads to a ton of string concatenation clogging up your code, and a mess of routes that are hard to maintain.
That's why I built make-route-map, an npm package which helps get your routing under control. It's 100% Typescript, and it lets you create a gorgeous, clean API for your routing which has type-safe routes, path parameters and search parameters.
I can't tell you how much stress it's saved me already. Refactoring or removing a route no longer takes dozens of find-in-files to remove the references. All that stress is Typescripted away.
The Basics
import { makeRouteMap } from 'make-route-map';
const routeMap = makeRouteMap({
  users: {
    path: '/users',
  },
  editUser: {
    path: '/users/:id/edit',
    params: {
      id: true,
    },
  },
  auth: {
    path: '/auth',
    search: {
      redirectPath: true,
    },
  },
});
console.log(routeMap.users());
// '/users'
console.log(routeMap.editUser({ params: { id: '240' } });
// '/users/240/edit'
console.log(
  routeMap.auth({
    search: { redirectPath: 'somewhere' },
  }),
);
// /auth?redirectPath=somewhere
The makeRouteMap function just creates a set of helpers which pull out the routes. You can pass in path parameters and search parameters.
Navigating
makeNavigate can take in a routeMap and a function to send you to a route, and will navigate you there when it's called.
const goToRoute = route => {
  window.location.href = route;
};
const navigate = makeNavigate(routeMap, goToRoute);
// This would take the user to '/users/240/edit'
navigate.editUser({
  params: {
    id: '240',
  },
});
This means you can plug in navigate into your current navigation implementation, like history.push.
Try it out
Let me know how you get on, and if you have any requests for the API. I'm so excited to have a pattern that's been working wonders for us public available.
 
 
              
 
    
Top comments (2)
Thanks! Would love the follow up on how to test an E2E map with Cypress and/or react-testing-library if you've done so :). I supposed it'd need to be RTL maybe since Cypress is at the browser level so you may not be able to import this hook?
This is awesome, I was just searching for how to do typesafe routes and your library came up, really slick!