Documentation
Feature Gating
Go beyond simple paywalls by combining middleware redirects, plan-aware helpers, and usage tracking. Everything lives alongside the Stripe config so you can resell the boilerplate with clear upgrade paths.
Choose Your Strategy
- Route-level gating: Middleware checks subscription status and reroutes users away from premium dashboards.
- Component-level gating: UI reads the current plan and hides unavailable features.
- Usage quotas:
UsageRecordentries track metrics such as API calls and storage.
Middleware
In src/middleware.ts, set ENABLE_SUBSCRIPTION_ENFORCEMENT="true" in your.env to block access to /dashboard/analytics, /dashboard/projects, and/dashboard/team unless token.stripeSubscriptionId exists. Customize thePREMIUM_ROUTES array to cover new pages.
Helper Functions
getUserPlan(stripeSubscriptionId, stripePriceId): resolves the plan key (FREE/STARTER/GROWTH/SCALE).isPlanFeatureEnabled(plan, feature): boolean switch for toggling UI.hasFeatureAccess(plan, feature, usage): enforce per-plan limits (pass current usage count).
import { getUserPlan, isPlanFeatureEnabled } from "@/lib/stripe";
const plan = getUserPlan(user.stripeSubscriptionId, user.stripePriceId);
if (!isPlanFeatureEnabled(plan, "analytics")) {
redirect("/dashboard/billing?upgrade=true");
}Usage Tracking
When you need metered usage, store counts in the UsageRecord model. Each record tracks a feature, the limit, and the current period. Update counts via cron job, queue, or directly inside API routes.
UI Patterns
- Show plan comparison cards (see
src/components/pricing-comparison.tsx). - Use toast notifications or inline alerts prompting users to upgrade when they hit limits.
- Add query params (e.g.,
?upgrade=true) so the billing page highlights the relevant plan.