The Sword Breaker
Posted on October 6, 2024
Writing because I did not find doc for setting clerk on the app router
Hey there! I was building an app using the T3 stack and decided to integrate the new auth provider clerk.io with t3 instead of nextAuth (which turned out to be a big mistake).
Unfortunately, it wasn't as developer-friendly as they claimed. (Only a few devs were harmed during the process.)
I encountered an issue when trying to add a clerk to trpc. I was following a clerk offical guide. The code provided works for a page router with trcp and not the app router.
/* server/context.ts */
import * as trpc from '@trpc/server'
import * as trpcNext from '@trpc/server/adapters/next'
import { getAuth } from '@clerk/nextjs/server'
export const createContext = async (opts: trpcNext.CreateNextContextOptions) => {
return { auth: getAuth(opts.req) }
}
export type Context = trpc.inferAsyncReturnType<typeof createContext>
In createContext definition,
CreateNextContextOptions is used to obtain the req, which is a pattern in the page router. At that time I did not know that. I tried to find different solutions but none worked
After a few thrilling adventures of TS Debugs of ...
- π€ΈββοΈ Type Gymnastics
- π Issue Hunting
- π» Blog Screening
and searching several Discord threads, I found something that works.
I'm using a completely new method from their updated API, which is not present in any older blogs. I hope they point out the correct way for the app router in the guides soon. Until then, try the following code.
/* server/trpc.ts */
import { currentUser } from "@clerk/nextjs";
import { initTRPC, TRPCError } from "@trpc/server";
import superjson from "superjson";
import { ZodError } from "zod";
import { db } from "~/server/db";
export const createTRPCContext = async (opts: { headers: Headers }) => {
const user = await currentUser();
return {
db,
user,
...opts,
};
};
// check if the user is signed in, otherwise throw an UNAUTHORIZED code
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.user?.id) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next({
ctx: {
user: ctx.user,
},
});
});
export const protectedProcedure = publicProcedure.use(isAuthed);
It's taken from this the very long hybrid discord thread but it works.
Posted on October 6, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.