T
TanStack5d ago
adverse-sapphire

Tanstack Router + React Query + Better Auth

Hi guys, anyone using tanstack router with better-auth? I have a question, which one you prefer for dasboard app? 1. prefer using useSession on every component that require user data or 2. prefer using getSession and wrap it with react query in root beforeLoad then put it on root context so i can access it on every component? then when i need to update user/session i invalidate the query on `root`
export const Route = createRootRoute({
beforeLoad: async () => {
const authData = await queryClient.ensureQueryData({
queryKey: ["auth", "session"] as const,
queryFn: async () => await authClient.getSession(),
staleTime: 5 * 60 * 1000,
gcTime: 10 * 60 * 1000,
});
return {
authData: authData.data,
};
},
component: RootComponent,
});
export const Route = createRootRoute({
beforeLoad: async () => {
const authData = await queryClient.ensureQueryData({
queryKey: ["auth", "session"] as const,
queryFn: async () => await authClient.getSession(),
staleTime: 5 * 60 * 1000,
gcTime: 10 * 60 * 1000,
});
return {
authData: authData.data,
};
},
component: RootComponent,
});
on login action / any related with changing user/session data i call refetchSessionQuery()
await authClient.signIn.email(value, {
onSuccess: async () => {
await refetchSessionQuery();
await router.invalidate();
}
})
await authClient.signIn.email(value, {
onSuccess: async () => {
await refetchSessionQuery();
await router.invalidate();
}
})
refetchSessionQuery function
export async function refetchSessionQuery() {
await queryClient.invalidateQueries({ queryKey: SESSION_QUERY_KEY });
return queryClient.refetchQueries({ queryKey: SESSION_QUERY_KEY });
}
export async function refetchSessionQuery() {
await queryClient.invalidateQueries({ queryKey: SESSION_QUERY_KEY });
return queryClient.refetchQueries({ queryKey: SESSION_QUERY_KEY });
}
then on every page i just use it like this
export const Route = createFileRoute("/_authenticated/dashboard")({
component: RouteComponent,
});
function RouteComponent() {
const authData = Route.useLoaderData();
return (
<div>
<p>User: {JSON.stringify(authData)}</p>
</div>
);
}
export const Route = createFileRoute("/_authenticated/dashboard")({
component: RouteComponent,
});
function RouteComponent() {
const authData = Route.useLoaderData();
return (
<div>
<p>User: {JSON.stringify(authData)}</p>
</div>
);
}
7 Replies
optimistic-gold
optimistic-gold5d ago
I've never used better auth, but I've used auth with router and the general approach is a mix of both. In your case, it seems like you would just want to put the authClient in the router context, then access the session in the router with authClient.getSession() and useSession in react components. This is similar in concept to how you would use react query between the two, where you put the queryClient in the router context for calling in loaders and beforeLoad, while using usequery in react. The problem with using useLoaderData is that it only updates if you invalidate the router, not when you invalidate your session. This leads to desync, so you should rely on the reactive hooks for auth in react, and the non-reactive methods in the router.
passive-yellow
passive-yellow5d ago
I have used the same approach, you can refer to this repo https://github.com/amanmavai/mn_projects
GitHub
GitHub - amanmavai/mn_projects
Contribute to amanmavai/mn_projects development by creating an account on GitHub.
passive-yellow
passive-yellow5d ago
as this a monorepo, check the tanstack_router_space app for this usage
adverse-sapphire
adverse-sapphireOP5d ago
oh you're wrapping authClient it self instead of only the session?
adverse-sapphire
adverse-sapphire4d ago
GitHub
GitHub - dotnize/react-tanstarter: 🏝️ minimal TanStack Start t...
🏝️ minimal TanStack Start template with Better Auth, Drizzle ORM, shadcn/ui - dotnize/react-tanstarter
adverse-sapphire
adverse-sapphireOP4d ago
those for tanstack start im looking for tanstack router. because im using monorepo and have 3 frontend 1 backend
adverse-sapphire
adverse-sapphire4d ago
what backend are u using?

Did you find this page helpful?