Feature: Lazy route tree registration for Module Federation micro frontends #7564
Replies: 3 comments
|
This is much needed one for my project too as i am already having this setup working with react-router and currently migrating it to tanstack router. |
|
I also encountered this issue when using TanStack Router with module federation. It would be great if the TanStack team explained the correct way to use TanStack Router with module federation in the documentation. |
|
I ran into this same wall, and ended up writing tanstack-router-remote (source) to get around it. We're taking it to production now, so sharing in case it helps anyone here while the thread waits for an official answer. pnpm add tanstack-router-remoteYou create the router with empty placeholder mounts, and each remote's tree gets grafted in later, the first time someone actually opens one of its URLs. Still one router, one history, one route cache. Works with React, Solid and Vue. const ordersMountRoute = createRemoteRoute({
getParentRoute: () => rootRoute,
path: '/orders',
component: OrdersMount,
})
function OrdersMount() {
return (
<RemoteRouteMount
mountRoute={ordersMountRoute}
loadRouteTree={async () =>
(await loadRemote('orders/routeTree')).routeTree
}
loading={<Spinner />}
>
<Outlet />
</RemoteRouteMount>
)
}So Direct links were the part that gave me the most trouble. Someone pastes Fair warning before anyone leans on it: it reaches into internals TanStack hasn't promised to keep ( A thought for the maintainersHonestly, I don't think this belongs in the router core. Most apps know their whole route tree at build time and would just be carrying the machinery around for nothing. An ecosystem package feels like a better fit, and I'd happily keep maintaining it in that role, under TanStack governance if you'd rather it live there. It's already shaped for it: framework-neutral core with React/Solid/Vue entries, open peer range with the canary watching it, limitations written down as a contract, runnable examples for each transport. The one thing I can't solve from outside is the route-tree surface I'm reaching through, which is precisely what bit me in 1.171.16. Three small seams would settle it for good:
The attach signature I landed on, plus the questions I couldn't answer from out here, are in docs/proposal.md. Either way, happy to feed the runtime findings back if any of it is useful. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Problem
When using TanStack Router with Module Federation micro frontends (MFEs), the entire route tree must be constructed before
createRouter()is called. This means all remote MFE route trees must be fetched and registered upfront at application startup, even if the user will only visit one or two of them during their session.In our case, we have 13 MFE remotes. We use
route.update()androute.addChildren()to inject each remote's route subtree into placeholder routes, then callcreateRouter(). This forces us to load all 13 remotes at startup viaPromise.allSettled, which:Promise.allSettled+ fallbacks, but it's still suboptimal)Current workaround
Where
registerSubtreedoes:Proposal
It would be great if TanStack Router supported lazy route tree registration — the ability to dynamically add children to a route at navigation time rather than only at startup.
One possible approach: allow
beforeLoadto register child routes dynamically. Something like:This way:
Context
This is a common challenge in Module Federation architectures where the host application doesn't know the remote's route structure ahead of time. The current requirement to have the full route tree before
createRouter()makes it difficult to achieve true per-route lazy loading of MFE bundles.Environment
@tanstack/react-router(file-based routing with Vite plugin)@module-federation/enhanced/runtimerouteTreeAll reactions