DinumaD
tRPC3y ago
3 replies
Dinuma

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"
      }
    })
})


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/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
Code for the tRPC on the App Router video. Contribute to jherr/trpc-on-the-app-router development by creating an account on GitHub.
trpc-on-the-app-router/src/app at main · jherr/trpc-on-the-app-router
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

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 };
Was this page helpful?