How to scope middleware errors to a layout boundary instead of root? #14190
-
I’d like some guidance on how to handle middleware in a way that keeps consistent user-experience across initial load and subsequent navigations with React Router I’m trying to guard everything under Desired behavior If a user without permissions navigates to Why I’m asking I want this to feel consistent on the initial load (all loaders run) and on client navigations (only affected loaders revalidate) without duplicating checks in every child route loader.
Reproduction: https://stackblitz.com/edit/github-zd8bdybn?file=app%2Froutes%2Fhome.tsx Question What’s the recommended approach to ensure a thrown 403 from a central guard for After thoughts
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 6 replies
-
You won't be able to do this in pure SPA mode based on the underlying architecture of a SPA. The const middlewareThatThrows: unstable_MiddlewareFunction<undefined> = async (
_args,
next
) => {
throw new Error("permission denied");
// This is what runs route.lazy for the matched routes and loads their implementations
// await next()
}; Throwing that error from a To do what you are looking for with middleware you need to go beyond a true SPA and start pre-rendering some pages specific to the edit route so you can get the layout route script in the initial HTML so it doesn't need to load via Change it to a route:
Then prerender the edit route:
Then you'll end up with Then, if you use |
Beta Was this translation helpful? Give feedback.
You won't be able to do this in pure SPA mode based on the underlying architecture of a SPA. The
index.html
used for SPA mode only renders the root route, and all other routes are lazily loaded viaroute.lazy
. By throwing in a middleware before calling next, those routes are never loaded so the router has no idea that theedit/layout
route has an error boundary so it has no choice but to bubble to the root route on initial load.Throwing that…