dex
dex
TtRPC
Created by dex on 5/7/2025 in #❓-help
tRPC does not have headers data when refreshing.
I'm using tanstack-start, tRPC and better-auth in my project and have it setup like this
export async function createContext(opts: CreateNextContextOptions) {
const session = await auth.api.getSession({ headers: opts.req.headers });

return {
db,
session: session?.user || null,
opts,
};
}

const t = initTRPC.context<typeof createContext>().create({
transformer: superjson,
});

export const createTRPCRouter = t.router;
export async function createContext(opts: CreateNextContextOptions) {
const session = await auth.api.getSession({ headers: opts.req.headers });

return {
db,
session: session?.user || null,
opts,
};
}

const t = initTRPC.context<typeof createContext>().create({
transformer: superjson,
});

export const createTRPCRouter = t.router;
I'm currently running into a problem where navigating normally in the app, I get the data that I need from tRPC. However, when reloading by CTRL+R I get UNAUTHORIZED since I'm using a protected procedure whichj looks like this:
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
if (ctx.session === null || ctx.session?.id === undefined) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session },
},
});
});
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
if (ctx.session === null || ctx.session?.id === undefined) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session },
},
});
});
So I investigated a little and have found that opts.req.headers just doesn't have the headers that I need. However, here's where I dont get it, the headers do absolutely exist. I verified this by creating a server function
const logWebRequest = createServerFn().handler(async () => {
console.log(
"\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",
getWebRequest(),
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n",
);
});
const logWebRequest = createServerFn().handler(async () => {
console.log(
"\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n",
getWebRequest(),
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n",
);
});
and using it on the loader like this before my trpc request
loader: async ({ context, params }) => {
await logWebRequest();
await context.queryClient.ensureQueryData(
context.trpc.vote.getAllVotes.queryOptions({ userId: params.me }),
);
}
loader: async ({ context, params }) => {
await logWebRequest();
await context.queryClient.ensureQueryData(
context.trpc.vote.getAllVotes.queryOptions({ userId: params.me }),
);
}
But when I do console.log(opts.req.headers) inside createContext it does not exist.
4 replies