Diagnosing bad context update behavior
Hey all, I'm facing a weird case of auth context not propagating from the
<RouterProvider />
into a route def's beforeLoad()
. This presents in layout components that should handle auth redirects not redirecting properly.
I've followed this https://tanstack.com/router/v1/docs/framework/react/examples/authenticated-routes example, and in InnerApp
I'm console logging the whole auth
object just to see what my context thinks the auth situation should be. Then I pass that auth into RouterProvider like this:
Then, in both layouts – the protected layout and the public layout – I have beforeLoad()
functions in the createRoute()
. In each beforeLoad I console log context.auth.isAuthenticated
.
Here's what my console looks like when I sign out of my app:
Landing me on a protected route with no user in the auth context, so my UI displays the error: "Cannot read properties of null."
Somewhere between the auth context (which gets updated properly and then immediately passed into the RouterProvider) and a top-level route, changes within the context.auth object available in the route's beforeLoad() are lost.
If I refresh the browser without touching anything, the app redirects me away from the protected route back to signin and stays there, but I don't understand why the hard refresh is necessary.
In my logout()
function I call router.invalidate()
before navigate()
.
Is there something I'm missing? Thanks!9 Replies
conscious-sapphire•16mo ago
The authenticated routes example, really is just an example of the patterns you can use when performing auth, but it really is upon you to adapt it to fit your application's specific needs.
If you are calling the
route.invalidate()
in your useAuth() hook that may cause an issue since that'd be outside the router's context, but again this is very much setup specific.
We'd need a minimal reproduction of whats going on here to fully understand the issue you are facing.metropolitan-bronzeOP•16mo ago
Okay! I'll try to spin one up and report back!
I was able to reproduce it in a fresh project! Both on signin and signout the app stayed on the route it was on instead of obeying the navigate, because the isAuthenticated value in context did not change when it should have
Here's the repo! https://github.com/tatwater/tanstack-router-reproduction
I'm trying to figure out how to best get this running locally for others for diagnostics, because it calls an api that's a separate repo in a local docker image, and that API is private to my company
But at the very least all the code is there, and maybe something jumps out at someone? I'm gonna keep trying
In the meantime, our workaround was to bypass the auth in router context and get it straight from localStorage
But because it's so weird that the auth context in react context is updating as expected, but the same value within the router's context isn't, I am happy to keep chasing this with someone in case it's a real bug, or if the docs could be clearer about an edge case or anything else that might be helpful!
wise-white•16mo ago
Hello, I'm facing the same issue,
i compared my code (https://github.com/SahilMahale/OishiDes/tree/master/oishi-ui) to the example code (https://tanstack.com/router/v1/docs/framework/react/examples/authenticated-routes) , the type of the context field is different in mine.
In my code the type is
context?:{}|undefined
and the one from the example has the type context:MyRouterContext
Although for me the value of auth
is being passed around properly , its just that my tsc
is complaining as its not able to see it.
PS: sorry if its redundant informationGitHub
OishiDes/oishi-ui at master · SahilMahale/OishiDes
A monorepo app to manage a boutique Restaurant, with a go backend, react-TS frontend and CI/CD(WIP) - SahilMahale/OishiDes
React TanStack Router Authenticated Routes Example | TanStack Route...
An example showing how to implement Authenticated Routes in React using TanStack Router.


conscious-sapphire•16mo ago
You need to use
createRootRouteWithContext
instead of createRootRoute
.wise-white•16mo ago
oh my bad tnx a lot
conscious-sapphire•16mo ago
Ideally, whenever, you auth stuff changes, you should be calling
router.invalidate()
. Its a matter, of where in your auth hook, or in the <InnerApp>
you are able to do this.grumpy-cyan•16mo ago
Just currious, would you also call
await queryClient.invalidateQueries()
if using TSQ also? I am doing this, but wasn't sure if it was needed or not. In fact, I run this:
conscious-sapphire•16mo ago
Depends on your conditions for updating the router from the auth hook.
You dont want to go create an infinite loop, where auth.updatedAt may change, where query gets invalidated, where auth.updatedAt changes, where query get invalidated, and so on.
grumpy-cyan•16mo ago
I see. Right now I have auth state outside of react context all-together. It seems to be working so far, but in the end I might end up switching it out with something more robust. Currently it is a waterfall of 3 async calls which is how I prevent it from infinite looping (if I were to use
Promise.all
then concurrency issues arise). I only do this for login/logout since I figured I really do want to clear all of the state when those actions occur. I've been thinking about giving preact signals a try, or zustand (based on your suggestion in another q/a). Thanks for the info! 🙂
