Skip to content

Routing declarations

When building client-side routing for a web app, organizing routes effectively is crucial.
The mobx-route library provides flexibility, but choosing the right structure for declaring routes can impact maintainability and scalability. Let’s explore two common patterns: the Separated and Collected approaches.

Separated way

In this approach, routes are declared near with the components, views, or view models they represent. Each feature or page owns its route configuration, promoting modularity.

Example Structure:

Home page

tsx
// src/pages/home/view.tsxexportconstHomePageView=()=><div>Home Page</div>;// src/pages/home/route.tsexportconsthomeRoute=newRoute('/');// src/pages/home/index.tsexport*from"./route";export*from"./view";

Death-star page

tsx
// src/pages/death-star/view.tsxexportconstDeathStarPageView=()=><div>Death Star Page</div>;// src/pages/death-star/route.tsexportconstdeathStarRoute=newRoute('/death-star');// src/pages/death-star/index.tsexport*from"./route";exportconstDeathStarPageView=loadable(async()=>{const{DeathStarPageView}=awaitimport('./view');returnDeathStarPageView})

App integration

tsx
// src/app/index.tsxexportconstApp=()=>{return(<><RouteViewroute={homeRoute}view={HomePageView} /><RouteViewroute={deathStarRoute}view={DeathStarPageView} /></>)}

Usage:

ts
deathStarRoute.open();

How It Works:

  1. Colocation: Routes and components live in the same feature directory (e.g.,pages/home), but are decoupled.
  2. Explicit Binding: TheRouteViewcomponent connects a route to its view at the app level.

Pros:

  • Modularity: Features encapsulate their own routes and views.
  • Clear Ownership: Teams can own entire features without conflicting with global routing.
  • Testability: Routes and views can be tested in isolation.

Cons:

  • No Global map: Navigation logic is distributed, making route hierarchy less visible.

Collected way

In this approach,all routes are centralized in a single configuration file, providing a unified map of the application’s navigation structure. This emphasizes visibility and centralized control over routing logic.

Example Structure:

routes configuration

ts
// src/shared/config/routing/routes.tsexportconstroutes={home:newRoute('/'),deathStar:newRoute('/death-star'),}

Home page

tsx
// src/pages/home/view.tsxexportconstHomePageView=()=><div>Home Page</div>;// src/pages/home/index.tsexport*from"./view";

Death-star page

tsx
// src/pages/death-star/view.tsxexportconstDeathStarPageView=()=><div>Death Star Page</div>;// src/pages/death-star/index.tsexportconstDeathStarPageView=loadable(async()=>{const{DeathStarPageView}=awaitimport('./view');returnDeathStarPageView})

App integration

tsx
// src/app/index.tsxexportconstApp=()=>{return(<><RouteViewroute={routes.home}view={HomePageView} /><RouteViewroute={routes.deathStar}view={DeathStarPageView} /></>)}

Usage:

ts
routes.deathStar.open();

How It Works:

  1. Centralized Configuration: All routes are defined inroutes.ts, acting as the app’s navigation map.
  2. Explicit Binding: TheRouteViewcomponent connects a route to its view at the app level.

Pros:

  • Single Source of Truth: All paths are visible in one place, simplifying debugging.

Cons:

  • Centralization Risks: Overcrowding in large apps (100+ routes).
  • Tight Coupling: Features depend on the central route file, complicating independent development.

When to Use Each Approach

Choose the Separated Way if:

  1. Building large-scale apps: Features are developed independently (e.g., micro-frontends).
  2. Prioritizing team autonomy: Multiple teams own specific domains/pages.
  3. Emphasizing reusability: Routes/views are shared across projects.

Choose the Collected Way if:

  1. Developing small/medium apps: A centralized route map remains manageable.
  2. Prioritizing simplicity: A single source of truth speeds up debugging.

Final Recommendation

  • Start with Collected Wayfor prototypes or small apps – it’s faster to implement.
  • Migrate to Separated Wayas complexity grows or team size increases.
  • Combine patterns strategically: Centralize core routes (e.g., auth, billing) while allowing feature-specific sub-routes.

Released under the MIT License.