Can I Serve tRPC With The NextJS App Router
Question: Can I serve tRPC with the NextJS App Router?
Answer: With some very minor modifications, absolutely. The popular T3 stack uses a setup where API endpoints on the Pages Router based NextJS server serve tRPC to the client. But the App Router uses a different mechanism for server API routes called Route Handlers. Thankfully it's pretty easy to create a Route Handler that interfaces to your tRPC server function.
First you need to put your tRPC API route handler in the right place. You'll probably want to put in the /app/api/trpc/[trpc]/route.tsx
file. This will mean that requests that go to /api/trpc/getTodos
, for example, will go to the getTodos
tRPC function. This is because the [trpc]
portion of the route tells NextJS to route requests to any route starting with /api/trpc
to that route and to store the value in the final route segment as the trpc
parameter.
In the route file we need to first include a different request handler:
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
The fetch
handler API surface aligns pretty easily with the App Router request format. So we'll use that.
Then we will bring in our definition for the appRouter
. This file can be located wherever you want. In this example it's in /server/index.ts
so the import looks like @/server
:
import { appRouter } from "@/server";
Finally we create handler function and use it for both the GET
and POST
functions exported from this route:
const handler = (req: Request) =>
fetchRequestHandler({
endpoint: "/api/trpc",
req,
router: appRouter,
createContext: () => ({}),
});
export { handler as GET, handler as POST };
The handler
request takes the incoming request (either GET or POST) and then sends it to the handler along with the endpoint URL (you would need to change this value if yours is different from /api/trpc
), the request, the appRouter
and then any context.
If your app uses authorization, which it probably does, you'll want to request the current user identity in the createContext
function and return it as part of the context object which is then sent to the server.
Other than that, it's business as usual for the awesome tRPC.