Custom protected routes?

Hey guys I'm wondering about the best way to achieve something.

I added a custom property to my User table which is ROLE

Role can be USER, ADMIN, or SUPER_ADMIN

I want to gate a route /admin and all of its potential future subroutes behind a check to ensure someones role is ADMIN.

const Admin = () => {
  const { data: sessionData } = useSession();

  const { data: isAdmin, isLoading: isAdminLoading } =
    api.user.isAdmin.useQuery(
      {
        userId: sessionData?.user?.id as string,
      },
      {
        enabled: sessionData?.user !== undefined,
      }
    );

  if (!isAdmin)
    return (
      <div>
        <H1>You are not authorized to view this page</H1>
      </div>
    );

  return <div>Admin</div>;
};

export default Admin;


  isAdmin: publicProcedure
    .input(
      z.object({
        userId: z.string(),
      })
    )
    .query(async ({ ctx, input }): Promise<boolean> => {
      return await ctx.prisma.user
        .findUnique({
          where: {
            id: input.userId,
          },
        })
        .then((user) => {
          if (user?.role === "ADMIN") return true;
          return false;
        });
    }),


I was adding this to each page but this seems obtuse / incorrect.

Is there a better way to gate entire routes behind custom checks than what I am doing here?
Was this page helpful?