How to make a fully public page with TRPC requests on T3?
I need to make a public page on T3 that calls for some public data from TRPC but I see that if I make any TRPC calls (even a simple hello world procedure) it fails and the console gives me errors regarding Clerk. How can I have some fully public page/data?
5 Replies
code?
did you use a public procedure?
did you added ignore trpc path in middleware?
Next.js: clerkMiddleware()
The
clerkMiddleware()
function allows you to protect your Next.js application using Middleware.Hey, yeah it's a public procedure @fotoflo
export const publicProcedure = t.procedure.use(sentryMiddleware);
getSinglePublicByID: publicProcedure
.input(ThreadCommonSchema)
.query(async ({ input, ctx }) => {
try {
return ctx.prisma.thread.findUnique({
where: { id: input.id, isPublic: true },
include: { messages: true },
});
} catch (err) {
handlePrismaTRPCError(err);
console.log("error is", err);
}
}),
This here is the middleware @Vanxh
import { authMiddleware, clerkClient, redirectToSignIn } from "@clerk/nextjs";
import { NextResponse } from "next/server";
// This example protects all routes including api/trpc routes
// Please edit this to allow other routes to be public as needed.
// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middleware
export default authMiddleware({
ignoredRoutes: ["/api/webhooks/stripe"],
async afterAuth(auth, req, evt) {
// Handle users who aren't authenticated
if (!auth.userId && !auth.isPublicRoute) {
return redirectToSignIn({ returnBackUrl: req.url });
}
if (auth.userId) {
const user = await clerkClient.users.getUser(auth.userId);
if (!user?.publicMetadata?.credits) {
await clerkClient.users.updateUserMetadata(auth.userId, {
publicMetadata: {
credits: 5000,
},
});
}
if (!user?.publicMetadata?.plan) {
await clerkClient.users.updateUserMetadata(auth.userId, {
publicMetadata: {
plan: "basic",
},
});
}
}
// If the user is signed in and trying to access a protected route, allow them to access route
if (auth.userId && !auth.isPublicRoute) {
return NextResponse.next();
}
// Allow users visiting public routes to access them
return NextResponse.next();
},
});
export const config = {
matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};
I would recommend you to migrate to clerk middleware as auth middleware is depreacted afaik https://clerk.com/docs/references/nextjs/overview#clerk-middleware
I think that you could remove
"/(api|trpc)(.*)"
from the matcher and handle auth directly in trpc like make a protected procedure.
Or do something like described here: https://canary.discord.com/channels/966627436387266600/1237558840736743435/1237797771562582129 .