Next cookies() not being set on Mutation in App Dir (T3 Turbo)

Trying to set cookies inside TRPC using Nextjs App Router, using the T3 Turbo setup. Setting cookies works fine inside Queries, but cookies are not set inside Mutations. Maybe I'm doing something wrong, not very up to date with TRPC + App Dir, or it could be a bug in next, not sure.
export const postRouter = createTRPCRouter({
all: publicProcedure.query(({ ctx }) => {
cookies().set("Cookies work on QUERY", "yes")
return [{id:0,
title: "query test",
content: "a test for trpc query",
createdAt: Date.now(),
updatedAt: Date.now()}]
}),

create: publicProcedure
.input(
z.object({
title: z.string().min(1),
content: z.string().min(1),
}),
)
.mutation(({ ctx, input }) => {
cookies().set("Cookies work on MUTATION", "No!")
console.log(cookies().getAll())
return 200;
}),
});
export const postRouter = createTRPCRouter({
all: publicProcedure.query(({ ctx }) => {
cookies().set("Cookies work on QUERY", "yes")
return [{id:0,
title: "query test",
content: "a test for trpc query",
createdAt: Date.now(),
updatedAt: Date.now()}]
}),

create: publicProcedure
.input(
z.object({
title: z.string().min(1),
content: z.string().min(1),
}),
)
.mutation(({ ctx, input }) => {
cookies().set("Cookies work on MUTATION", "No!")
console.log(cookies().getAll())
return 200;
}),
});
After calling both the query and the mutation on frontend you only get the cookie from the Query. But this gets logged to console.
@acme/nextjs:dev: [
@acme/nextjs:dev: { name: 'Cookies work on QUERY', value: 'yes', path: '/' },
@acme/nextjs:dev: { name: 'Cookies work on MUTATION', value: 'No!', path: '/' }
@acme/nextjs:dev: ]
@acme/nextjs:dev: [
@acme/nextjs:dev: { name: 'Cookies work on QUERY', value: 'yes', path: '/' },
@acme/nextjs:dev: { name: 'Cookies work on MUTATION', value: 'No!', path: '/' }
@acme/nextjs:dev: ]
(this is after calling the query first then the mutation.)
IceAge2OnDVD
IceAge2OnDVD253d ago
Sorry for thing ping but I feel like I may need some more expert help on this @marminge I though that it may be something to do with not being able to set cookies after streaming starts, but then it doesn’t make sense how cookies work in query but not mutation At least it doesn’t make sense to me
_jdow
_jdow253d ago
I’m also struggling with the same issue in app router. I found that it’s actually the .input() that breaks cookies from settings correctly. Both query or mutation sets cookies properly with a hardcoded value and no .input() but as soon as you add the .input() (even if you still use a hardcoded value for the cookie) it doesn’t get set Really hoping to find a solution, but don't really know where to go from here 😢
IceAge2OnDVD
IceAge2OnDVD252d ago
Is there on open issue for this?
_jdow
_jdow252d ago
I haven't had too much time to look into it, but not that I could find Probably a good idea to open one about it
mattddean
mattddean248d ago
It seems like unstable_httpBatchStreamLink has this problem, but httpBatchLink does not
Lucas
Lucas248d ago
If you're using unstable_httpBatchStreamLink, headers are returned at the beginning of the request (since the response is a streamed response). This means you can't set any headers or cookies inside procedures. httpBatchLink does not have this issue due to the response not being streamed.
IceAge2OnDVD
IceAge2OnDVD247d ago
Ahhh i see makes sense is there a way you could make it so that certain mutations are never streamed? Like use a regular http link for certain routes
IceAge2OnDVD
IceAge2OnDVD247d ago
https://trpc.io/docs/client/links/splitLink , i'm going to have a look at using split links, see if that works
Split Link | tRPC
splitLink is a link that allows you to branch your link chain's execution depending on a given condition. Both the true and false branches are required. You can provide just one link, or multiple links per branch via an array.
IceAge2OnDVD
IceAge2OnDVD247d ago
Managed to get it working, basically the answer is to avoid batchStreamLink on any routes/paths that need to set cookies.
export function TRPCReactProvider(props: {
children: React.ReactNode;
headers: Headers; // <-- Important
}) {
const [queryClient] = useState(() => new QueryClient());

const [trpcClient] = useState(() =>
api.createClient({
transformer,
links: [
unauthenticatedHandler,
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === "development" ||
(opts.direction === "down" && opts.result instanceof Error),
}),
splitLink({
condition(op) {
// Add logic here to return true for paths/routes that need to set cookies
return op.path.startsWith("auth.");
},
true: httpBatchLink({
url: getUrl(),
headers() {
const heads = new Map(props.headers);
heads.set("x-trpc-source", "react-no-stream");
return Object.fromEntries(heads);
},
}),
false: unstable_httpBatchStreamLink({
url: getUrl(),
headers() {
const heads = new Map(props.headers);
heads.set("x-trpc-source", "react-stream");
return Object.fromEntries(heads);
},
}),
}),
],
}),
);
export function TRPCReactProvider(props: {
children: React.ReactNode;
headers: Headers; // <-- Important
}) {
const [queryClient] = useState(() => new QueryClient());

const [trpcClient] = useState(() =>
api.createClient({
transformer,
links: [
unauthenticatedHandler,
loggerLink({
enabled: (opts) =>
process.env.NODE_ENV === "development" ||
(opts.direction === "down" && opts.result instanceof Error),
}),
splitLink({
condition(op) {
// Add logic here to return true for paths/routes that need to set cookies
return op.path.startsWith("auth.");
},
true: httpBatchLink({
url: getUrl(),
headers() {
const heads = new Map(props.headers);
heads.set("x-trpc-source", "react-no-stream");
return Object.fromEntries(heads);
},
}),
false: unstable_httpBatchStreamLink({
url: getUrl(),
headers() {
const heads = new Map(props.headers);
heads.set("x-trpc-source", "react-stream");
return Object.fromEntries(heads);
},
}),
}),
],
}),
);
More Posts
tRPC error in app Router (undefined headers)I use the tRPC file structure from Jack Herringtons video I added clerk auth for protected routes anBad request in prod but works fine in devin prod I am getting `BAD REQUEST`hey is there any way to integrate or implement machine learning / ai in trpcSpecifically for next.js or tensorflow?How to serve files with trpc?Is is possible to serve files with trpc? E.g., by creating a middleware and returning directly from tRPC in Next without api rotesHello! I have NextJS app that gets data in gSP using some third-party client. This data comes untypegetting the progress of a trpc queryHello, I want to be able to stream the progress of a trpc client query call, so I can link it to a pwrapper on useMutation (and another for useQuery) for creating multiple hookshi i want to create a wrapper for my router, basically I would like to achive somethink like that useQuery returning old data with new paramsI have a react component that takes in a date range and calculates a users net worth (sums up all asCalling a tRPC service from another tRPC serviceI have 2 services (App1 and Service2) App1 is client facing and uses trpc well But occasionally App1charset=utf8 results in empty inputI'm using trpc-openapi and some of our customers are using Zapier to communicate with it. Zapier usIs there a way to alter the query key generated by trpc?I want to pass a boolean flag (`initial`) to the backend saying if it's a first call of a given procuseMutation throwing 500 errorsI've setup my next 13 app router project and started using some queries that worked fine, however thTRPC Nextjs App Router API Base URLIs there any issues with me placing trpc route handler in the root of my api folder? I don't really Turborepo, nextjs, vite react app, express serverI have following structure Apps: First Frontend - Nextjs app Second Frontend - Vite ReactApp BackenRouter/Middleware Chaining in V10Heyo, finally migrating from v9 to v10 after putting it off for a while. Is it just me, or is this mthrowing custom errors from mutationsany idea why trpc is ignoring the catch expression? it just throws its own error about unique consttrpc in a pnpm monorepoHi all 👋 I was wondering if there is a recommended setup for monorepos, in our case with pnpm workTS Error with React when creating client "useContext" collides ....when creating the client i get following error: The property 'useContext' in your router collides wType 'NextRequest' is missing properties from type 'NextApiRequest'Enviorment: Node 18, pnpm Hi, I'm facing an error, where in my app i get this error at `createTRPCCType '{}' is not assignable in server queryType '{ input: { slug: string; }; "": any; }' is not assignable to type 'string | StringFilter<"Cate