T
TanStack11mo ago
rival-black

Using the beforeLoad in the root component breaks UI functionality (shadcn ui)?

In my root component, I have a simple server function that fetches the user and session from the session cookie in the beforeLoad function. app/routes/__root.tsx
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()(
{
beforeLoad: () => {
return validateRequest();
},

...
}
);
export const Route = createRootRouteWithContext<{ queryClient: QueryClient }>()(
{
beforeLoad: () => {
return validateRequest();
},

...
}
);
As soon I add this line of code or really any server function down the tree in beforeLoad, my dialogs, dropdowns, and any other interactive component no longer becomes interactive. I am using the default configuration for shadcn UI and without this line, all of my features become interactive again. I was under the impression that all route components were client side components in TanStack start even though it's an SSR framework? Anyone want to break down what's happening here for me? I am trying to use TanStack query with the ensureQueryData and useSuspenseQuery pattern in the app, but I don't want all my buttons to break as a result :/
5 Replies
quickest-silver
quickest-silver11mo ago
what does validateRequest do? a complete minimal example would be helpful
rival-black
rival-blackOP11mo ago
It just checks for a session cookie, the name could be more obvious but the functionality overall is this.
import { User } from "lucia";
import { lucia } from "./lucia";
import { createServerFn } from "@tanstack/start";

export const validateRequest = createServerFn("GET", async (_, { request }) => {
const cookieHeader = request.headers.get("Cookie");

const sessionId = lucia.readSessionCookie(cookieHeader ?? "");
if (!sessionId) {
return {
user: null,
session: null,
};
}

const headers = new Headers();

const { session, user } = await lucia.validateSession(sessionId);
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie();
headers.append("Set-Cookie", sessionCookie.serialize());
}

if (session && session.fresh) {
const sessionCookie = lucia.createSessionCookie(session.id);
headers.append("Set-Cookie", sessionCookie.serialize());
}

return { user, session };
});
import { User } from "lucia";
import { lucia } from "./lucia";
import { createServerFn } from "@tanstack/start";

export const validateRequest = createServerFn("GET", async (_, { request }) => {
const cookieHeader = request.headers.get("Cookie");

const sessionId = lucia.readSessionCookie(cookieHeader ?? "");
if (!sessionId) {
return {
user: null,
session: null,
};
}

const headers = new Headers();

const { session, user } = await lucia.validateSession(sessionId);
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie();
headers.append("Set-Cookie", sessionCookie.serialize());
}

if (session && session.fresh) {
const sessionCookie = lucia.createSessionCookie(session.id);
headers.append("Set-Cookie", sessionCookie.serialize());
}

return { user, session };
});
quickest-silver
quickest-silver11mo ago
what does this mean? " my dialogs, dropdowns, and any other interactive component no longer becomes function. "
rival-black
rival-blackOP11mo ago
Sorry I mean to say interactive. As in when I click on a select, nothing happens. When I click on a trigger for a modal, nothing happens. If I remove this line of code, they all become interactive again. Sorry, ESL moment lol This line of code meaning the beforeLoad logic bump This feels like I'm missing something key in my understanding of client/server relations in tanstack start
quickest-silver
quickest-silver11mo ago
please provide a minimal complete example, e.g. by forking one of the existing examples on stackblitz

Did you find this page helpful?