trpc context doesn't sync to "local" context
vloe opened this issue · 6 comments
Describe the bug
can't seem to use the trpc context like the local context. example: you can set cookie in load function with event.cookie.set(...), but this doesn't work with trpc context.
To Reproduce
Steps to reproduce the behavior:
- return event in context:
// lib/trpc/context
export async function createContext(event: RequestEvent) {
return {
event
};
}
- use context to set cookie:
// lib/trpc/routes/auth
ctx.event.cookies.set('token', Md5.hashStr(email));
Expected behavior
whenever the event from trpc context changes, it should sync with "local" context. if not expected behavior how does one do this?
I am dealing exactly with the same issue. It's not a bug of this repo though.
trpc
creates it's own response, so updating cookies on event
doesn't make sense.
What works is:
createContext: ({ req, resHeaders }) => {
return {resHeaders};
})
and later you can do:
ctx.resHeaders.set("set-cookie", cookie.serialize("authToken", session.authToken));
but that's a very ugly workaround, so I wonder what's the expected pattern in this case.
🤞 @icflorescu can give us a better hint.
thanks @michaltaberski, but I didn't manage to get your solution to work. this is the closest I've gotten:
// hooks.server.ts
export const handle = createTRPCHandle({
router,
createContext,
responseMeta() {
return {
headers: {
'set-cookie': 'test'
}
};
}
}) satisfies Handle;
there should definitely be a better way of doing this. isn't the whole point of trpc (besides typesafety) to have full control over the response? otherwise one could just use normal serverless functions...
I’m running into the same problem when trying to set cookies or headers inside a truck procedure.
I'm also having troubles with this when trying to delete or update a cookie initially set in a non tRPC endpoint.
For anyone running into this, one way I've found to still use SvelteKit cookies is to manually add them through the Response Meta. You can create the tRPC Handler like this:
const trpcHandler = createTRPCHandle({
router: appRouter,
createContext,
// @ts-expect-error: `responseMeta` expects `headers` to be `Record<string, string>` but `Record<string, string | string[]>` works .
responseMeta({ ctx, type }) {
if (ctx && (type === "mutation" || type === "query")) {
const { cookies } = ctx;
return {
headers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
"set-cookie": cookies
.getAll()
.map(({ name, value }) =>
cookies.serialize(name, value, cookieOptions)
),
},
};
}
return {};
},
}) satisfies Handle;
This will allow you to use SvelteKit cookies in your queries and mutations.
Can confirm @allezxandre's solution works fine, thank you! (: