Implementing Component rotection Based on Subscription Plans
To protect Components based on a user's subscription plan, you can add the following hook to your codebase. This will be available in future releases > V1.1.0.
Add this hook in the hooks path: (hooks/use-subscribed.ts)
import { getClientPlan } from "@/actions/client/payment/stripe/subscriptions";
import { SubscriptionPlan } from "@prisma/client";
import { useQuery } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
export function useSubscribed() {
const { data: session } = useSession();
const { data: clientPlan } = useQuery({
queryKey: ["clientPlan"],
queryFn: async () => await getClientPlan(),
enabled: !!session,
});
const checkSubscription = (plan: SubscriptionPlan, type?: string) => {
if (!clientPlan) return false;
const matchesPlan = clientPlan.subscriptionPlan === plan;
return type
? matchesPlan && clientPlan.subscriptionType === type
: matchesPlan;
};
// Allow admins to access all features since enterprise plans have access to all features
const isAdmin = session?.user.roles.includes("ADMIN");
return {
starterPlan: checkSubscription(SubscriptionPlan.STARTER),
premiumPlan: checkSubscription(SubscriptionPlan.PREMIUM, "RECURRING"),
plusPlan: checkSubscription(SubscriptionPlan.PLUS, "RECURRING"),
enterprisePlan:
checkSubscription(SubscriptionPlan.ENTREPRISE, "ONETIME") ||
isAdmin,
};
}
How to use it
Suppose you have a client component that only users subscribed to the Plus plan can access:
"use client";
import { useSubscribed } from "@/hooks/use-subscribed";
export default function Component() {
const { data: session, status } = useSession();
const isSubscribed = useSubscribed();
if (status === "loading") {
return <Icons.spinner className="mx-auto h-12 w-12 animate-spin" />;
}
if (!isSubscribed || !isSubscribed.plusPlan) {
return (
<div className="text-center mt-10">
You need to subscribe to the Plus plan to access this component.
</div>
);
}
return (
<Card className="">
Content
</Card>
);
}