Contextual feature locking for React that doesn't interrupt flow
Demo โข Documentation โข Blog Post
Feature Lock is a collection of React components for building contextual upgrade experiences. Instead of redirecting users to pricing pages, show upgrade prompts directly on the features they want to unlock.
Traditional paywalls interrupt the user experience:
- Click "Export Report" โ Redirected to pricing page
- Context is lost
- User forgets why they clicked
- Lower conversion rates
Feature Lock keeps users in context:
- Click "Export Report" โ Overlay appears on the locked feature
- Clear upgrade prompt right where they need it
- User understands the value immediately
- Higher conversion rates
The flagship component that blurs locked features and guides users to upgradeโwithout breaking their flow.
npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapperimport { useState } from "react"
import BlurWrapper from "@/components/blurWrapper/blur-wrapper"
export function LockedFeature() {
const [locked, setLocked] = useState(true)
async function handleUpgrade() {
await fetch("/api/upgrade", { method: "POST" })
setLocked(false)
}
return (
<BlurWrapper
isBlurred={locked}
onConfirm={handleUpgrade}
onUnblur={() => setLocked(false)}
>
<YourPremiumContent />
</BlurWrapper>
)
}View Full BlurWrapper Documentation โ
Dismissible announcement banner that spotlights new or locked functionality, provides upgrade CTAs, and respects user choice with optional local persistence.
- Async primary & secondary actions with loading/error states
- Variants for upgrade, info, success, and warning messages
- Optional
storageKeyto remember dismissals across visits
Install directly into your project:
npx shadcn@latest add https://feature-lock.griffen.codes/r/paywall-bannerInline tooltip for gently nudging upgrades without interrupting users. Ideal for inline icons, disabled buttons, or table cells.
- Accessible Radix tooltip trigger on hover/focus
- Optional CTA (link or async action) with pending/error states
- Highlight list for feature value props
Install it with one command:
npx shadcn@latest add https://feature-lock.griffen.codes/r/feature-tooltipStandalone upgrade dialog that compares plans, highlights value props, and routes users to checkout flows.
- Supports async CTAs and links per plan with pending/error states
- Automatically adapts layout for one, two, or three plan offerings
- Includes fine print, support contact callout, and recommended badge styling
Install directly:
npx shadcn@latest add https://feature-lock.griffen.codes/r/upgrade-modalQuota dashboards that show consumption trends, warn before limits, and route users to upgrade flows.
- Per-track badges, trend arrows, and progress bars
- Summary banner with plan unlock messaging and CTA row
- Async upgrade handler with error feedback and secondary actions
Add it to your project:
npx shadcn@latest add https://feature-lock.griffen.codes/r/usage-progress- More components - Additional monetization patterns coming soon
Make sure you have a Next.js project with shadcn/ui set up:
npx shadcn@latest initInstall the BlurWrapper component:
npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapperThis installs:
- BlurWrapper component
- Required shadcn/ui components (Button, Dialog)
- All necessary dependencies
import { useState } from "react"
import BlurWrapper from "@/components/blurWrapper/blur-wrapper"
export function Dashboard() {
const [analyticsLocked, setAnalyticsLocked] = useState(true)
return (
<BlurWrapper
isBlurred={analyticsLocked}
overlayMode="inline"
inlinePosition="centerCenter"
onConfirm={async () => {
await upgradeUserPlan()
}}
onUnblur={() => setAnalyticsLocked(false)}
>
<AdvancedAnalytics />
</BlurWrapper>
)
}Dialog Mode - Full-screen modal for critical upgrade decisions Inline Mode - Contextual overlay positioned directly on locked content
- Async-Ready: Built with React 19's
useTransitionfor seamless async operations - Secondary Actions: Optional secondary button for "Learn More" or "Contact Sales" actions
- Custom Icons: Replace the default Lock icon with any Lucide icon
- Accessible by Default: Focus blocking with
inert, screen reader announcements, error focus management - Flexible Positioning: 9 position options for inline overlays
- Custom Overlays: Full control with render props
- Error Handling: Built-in error states with automatic focus management
See the component README for detailed examples and API documentation.
For complete API documentation, advanced examples, and implementation patterns, see:
- Component README - Full technical reference
- Live Documentation - Interactive examples
For more examples including custom error handling, controlled state, and advanced patterns, see the component README.
- React 19 - UI library with useTransition
- Next.js 14+ - React framework
- TypeScript - Type safety
- Tailwind CSS - Styling
- shadcn/ui - Component library
- Radix UI - Accessible primitives
- Gating premium features (analytics, exports, advanced tools)
- Contextual upgrade prompts in dashboards
- Freemium SaaS products
- Trial limitations
- Feature-based pricing tiers
- Full page paywalls (use traditional pricing pages)
- Content behind authentication (use proper auth)
- Critical security features (don't rely on client-side blur)
Feature Lock components are distributed via a ShadcnUI-compatible registry. This means:
โ Easy Installation - One command installs everything โ Automatic Dependencies - No manual package.json editing โ Version Management - Registry tracks component versions โ Full Source Code - Components installed in your project (not node_modules)
| Component | Status | Command |
|---|---|---|
| BlurWrapper | โ Stable | npx shadcn@latest add https://feature-lock.griffen.codes/r/blur-wrapper |
| PaywallBanner | โ New | npx shadcn@latest add https://feature-lock.griffen.codes/r/paywall-banner |
| FeatureTooltip | โ New | npx shadcn@latest add https://feature-lock.griffen.codes/r/feature-tooltip |
| UpgradeModal | โ New | npx shadcn@latest add https://feature-lock.griffen.codes/r/upgrade-modal |
| UsageProgress | โ New | npx shadcn@latest add https://feature-lock.griffen.codes/r/usage-progress |
| AgeGate | โ New | npx shadcn@latest add https://feature-lock.griffen.codes/r/age-gate |
The registry exposes these endpoints:
GET /api/registry- List all componentsGET /api/registry/r/:name- Get specific component
Learn more about the registry โ
This project includes Vercel Analytics integration to track:
- Component installations
- Documentation engagement
- Demo interactions
- Conversion funnels
We love contributions! Whether you want to:
- ๐ Report bugs
- โจ Suggest features
- ๐ Improve documentation
- ๐ป Submit code
- ๐จ Design new components
Check out our Contributing Guide โ
# Clone the repo
git clone https://github.com/gfargo/feature-lock.git
cd feature-lock
# Install dependencies
npm install
# Start dev server
npm run dev
# Generate registry
npm run gen:registryVerify your tsconfig.json:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}Ensure content has non-transparent background:
<BlurWrapper isBlurred={locked}>
<div className="bg-white dark:bg-slate-900">
{/* Content */}
</div>
</BlurWrapper>Check that showOverlayOnBlur is not false:
<BlurWrapper
isBlurred={locked}
showOverlayOnBlur={true} // Default
>
<Content />
</BlurWrapper>View Full Troubleshooting Guide โ
MIT ยฉ Griffen Labs
See LICENSE for details.
- shadcn - For the amazing component library and CLI architecture
- Radix UI - For accessible, unstyled primitives
- Vercel - For hosting and analytics
- React Team - For useTransition and concurrent features
- Live Demo - Try it yourself
- Documentation - Full API reference
- Blog Post - Design philosophy
- GitHub Issues - Report bugs
- Discussions - Ask questions
- โ BlurWrapper component
- โ PaywallBanner component
- โ FeatureTooltip component
- โ UpgradeModal component
- โ UsageProgress component
- โ Dialog and inline modes
- โ Async handling with useTransition
- โ Full accessibility support
- โ Component registry
- โ Documentation site
- โ Analytics integration
- ๐ง Additional positioning options
- ๐ง Animation customization
- ๐ฎ Internationalization (i18n)
- ๐ฎ Vue and Svelte versions
- ๐ฎ Storybook documentation
If Feature Lock helps your project, please give it a star on GitHub! It helps others discover the project.