T
TanStack•9mo ago
manual-pink

How to handle authentication (get session data)

My knowledge on this has atrophied. 😩 With NextJS I'm so used to having async as the default. Now that I'm with Tanstack Router this isn't the case (as of now). I'm struggling how to use
const session = await authClient.getSession()
const session = await authClient.getSession()
Imagine I have the following:
import { authClient } from '@acme/auth';
import { Group, Stack } from '@raikou/core';

function AssetContainer() {
const getSession = async () => {
const { data } = await authClient.useSession();
return data?.user.id;
};
const userId = await getSession();

return (
<Stack>
<Group align="flex-start" gap={0}>
<Content userId={userId} />
</Group>
</Stack>
);
}

export default AssetContainer;
import { authClient } from '@acme/auth';
import { Group, Stack } from '@raikou/core';

function AssetContainer() {
const getSession = async () => {
const { data } = await authClient.useSession();
return data?.user.id;
};
const userId = await getSession();

return (
<Stack>
<Group align="flex-start" gap={0}>
<Content userId={userId} />
</Group>
</Stack>
);
}

export default AssetContainer;
Now that AssetContainer needs to be async due to the await. Does each parent function now needs async, until I go up the chain to the Route? I've tried using use with React 19 but unfortunately this doesn't work. How should I approach this? Looking for best practice. Note: I did check the docs to see if there was a way of passing down data from the Router to the top level component and didn't see this was the case.
3 Replies
manual-pink
manual-pinkOP•9mo ago
I decided to make the AssetContainer function async. I then wrapped it in the parent component within suspense. It works but now I get:
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
Am I approaching this the wrong way? Should I be using Start instead? https://github.com/TanStack/router/blob/main/examples/react/authenticated-routes/src/auth.tsx#L16-L26 I see the use of localStorage employed. So I decided to use this instead. In the top level entry point of the app.
export const Route = createFileRoute('/')({
component: HomeComponent,

beforeLoad: async ({ context }) => {
const { getSession } = context.authentication;
const { data } = await getSession();

if (data === null) {
throw redirect({
to: '/login',
});
} else if (context.localStorage.getItem() === '') {
context.localStorage.setItem(data.user.id);
}
},
});
export const Route = createFileRoute('/')({
component: HomeComponent,

beforeLoad: async ({ context }) => {
const { getSession } = context.authentication;
const { data } = await getSession();

if (data === null) {
throw redirect({
to: '/login',
});
} else if (context.localStorage.getItem() === '') {
context.localStorage.setItem(data.user.id);
}
},
});
quickest-silver
quickest-silver•9mo ago
The example you showed in the OP seems like a server component. These are not yet supported in TanStack Start (which will eventually support them). For now you can use React Query useQuery hook + TanStack Start queryClient.ensureQueryData to simulate it.
manual-pink
manual-pinkOP•9mo ago
The example you showed in the OP seems like a server component.
Very True. I'm trying to kick the old NextJS habit of the past 4+ years 😂 and trying to relearn new patterns.
For now you can use React Query useQuery
I'm wanting to avoid an over-reliance on that. As I'm going to be using either zero/electric-sql/jazz-tools or some other mechanism for interface with the database.

Did you find this page helpful?