Dinuma
Dinuma10mo ago

Help Retrieving req.url from opts in useMutation from tRPC

Hello, i'm trying to essentially send a magiclink email using supabase client libraries, however, i'm running into an issue of not being able to retrieve the req.url (in order to get the baseURL). I would prefer not to hard-code it due to changing addresses between localhost, Vercel Preview Branches, Primary Domain. Code Context
export const authRouter = router({
email_login: publicProcedure
.input(UserAuthFormSchema)
.mutation(async (opts) => {
await handleEmailLogin(opts.input.email, "baseURL");

return {
message: "Success"
}
})
})
export const authRouter = router({
email_login: publicProcedure
.input(UserAuthFormSchema)
.mutation(async (opts) => {
await handleEmailLogin(opts.input.email, "baseURL");

return {
message: "Success"
}
})
})
I believe the way to go here is to utilize a context, however, i'm having trouble setting that up throughout the react-query client portion alongside with the server portion. My current repo is 1:1 to jherr's nextjs App Router setup, except it has this auth router composing into the primary appRouter. https://github.com/jherr/trpc-on-the-app-router/tree/main/src/app I'm confused on how to override the fetchRouterHandler on the client side to properly pass through the req / res object. Attempt at making the context
// @api-server/context.ts
export async function createContext(opts: CreateNextContextOptions) {
return {
req: opts.req,
};
}
// @api-server/context.ts
export async function createContext(opts: CreateNextContextOptions) {
return {
req: opts.req,
};
}
// @/api-server/trpc.ts
import { initTRPC } from "@trpc/server";
import { createContext } from "./context";

const t = initTRPC.context<typeof createContext>().create();

export const router = t.router;

export const publicProcedure = t.procedure.use((opts) => {
if (!opts.ctx.req) {
throw new Error('You are missing `req` in your call.');
}

return opts.next({
ctx: {
// We overwrite the context with the truthy `req` & `res`, which will also overwrite the types used in your procedure.
req: opts.ctx.req,
},
});
});
// @/api-server/trpc.ts
import { initTRPC } from "@trpc/server";
import { createContext } from "./context";

const t = initTRPC.context<typeof createContext>().create();

export const router = t.router;

export const publicProcedure = t.procedure.use((opts) => {
if (!opts.ctx.req) {
throw new Error('You are missing `req` in your call.');
}

return opts.next({
ctx: {
// We overwrite the context with the truthy `req` & `res`, which will also overwrite the types used in your procedure.
req: opts.ctx.req,
},
});
});
GitHub
trpc-on-the-app-router/src/app at main · jherr/trpc-on-the-app-router
Code for the tRPC on the App Router video. Contribute to jherr/trpc-on-the-app-router development by creating an account on GitHub.
Solution:
I just figured it out, it was my lack of understanding that the fetchRouterHandler was meant for edge runtimes, and I had to change my createContext function to FetchCreateContextFnOptions change my trpc route handler appropriatly for the fetchRouter: /app/api/trpc/[trpc]/route.ts ```ts import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import { appRouter } from "@/api-server";...
Jump to solution
1 Reply
Solution
Dinuma
Dinuma10mo ago
I just figured it out, it was my lack of understanding that the fetchRouterHandler was meant for edge runtimes, and I had to change my createContext function to FetchCreateContextFnOptions change my trpc route handler appropriatly for the fetchRouter: /app/api/trpc/[trpc]/route.ts
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "@/api-server";
import { NextRequest } from "next/server";

// Running on serverless node in Vercel instead, despite using fetchRouteHandler

export default async function handler(req: Request) {
return fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
req: req,
createContext: () => ({req}),
})
}

export { handler as GET, handler as POST };
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "@/api-server";
import { NextRequest } from "next/server";

// Running on serverless node in Vercel instead, despite using fetchRouteHandler

export default async function handler(req: Request) {
return fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
req: req,
createContext: () => ({req}),
})
}

export { handler as GET, handler as POST };