A collection of high-converting web funnels built with Next.js. Web funnels are one-question-per-screen conversion flows optimized for mobile-first user experiences, commonly used for lead generation, surveys, onboarding, and qualification flows.
- One-Question-Per-Screen - Each question or benefit gets its own dedicated screen for better conversion
- Mobile-First Design - Optimized for mobile traffic with responsive layouts
- Rich Component Library - Cards, sliders, wheels, star ratings, emotion selectors, and more
- Progress Tracking - Visual progress bar with back navigation
- State Persistence - localStorage-based state management with hydration handling
- Analytics Ready - Facebook Pixel, Matomo, and Sentry integrations
- Payment Integration - Stripe payments with webhook event handling
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS |
| Analytics | Facebook Pixel + Conversions API, Matomo |
| Payments | Stripe |
| Error Tracking | Sentry |
| Deployment | Vercel |
- Node.js 18+ and npm
- Vercel Account (for deployment) - vercel.com
Optional (for full functionality):
- Stripe Account - for payment processing
- Facebook Business Account - for conversion tracking
- Sentry Account - for error monitoring
# Clone the repository
git clone https://github.com/ozma-io/web-funnels.git
cd web-funnels
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:3000 to view the funnels.
app/your-funnel-name/
├── README.md # Business logic and screen descriptions
├── page.tsx # Main funnel page with state management
├── design/ # Optional: Figma exports by date
│ └── 2025-01-18/
│ ├── Question_1.png
│ └── Question_2.png
└── screens/
├── 001-HeroScreen.tsx
├── 002-QuestionOneScreen.tsx
├── 003-QuestionTwoScreen.tsx
└── 004-ThankYouScreen.tsx
- Prefix files with 3-digit IDs:
001-,002-,003- - Use descriptive names:
001-HeroScreen.tsx,002-GoalSelectionScreen.tsx - Import screens in numeric order in
page.tsx
Use the funnel storage utility for state persistence:
import { getFunnelState, setFunnelState } from '@/app/utils/funnelStorage';
// Save state
setFunnelState('your-funnel', { step: 2, answers: {...} });
// Load state
const state = getFunnelState('your-funnel');Use different interactive components for consecutive screens to maintain engagement. See the Component Library below.
The app/components/ directory contains reusable question components:
| Component | Use Case |
|---|---|
QuestionCardsScreen |
Masonry-style grid cards with icons |
QuestionRadioScreen |
Standard radio button list |
QuestionMultiSelectPillsScreen |
Pill-shaped multi-select buttons |
QuestionSliderScreen |
Horizontal slider with labels |
QuestionSliderVerticalScreen |
Vertical slider with emotion icons |
QuestionWheelScreen |
Colorful semicircular wheel selector |
QuestionStarsScreen |
5-star rating with emotion feedback |
QuestionEmotionSelectorScreen |
Emotion icon selector |
All components share a common interface:
interface QuestionScreenProps {
question: string
options: string[]
value: string
onChange: (value: string) => void
onNext: () => void
}See app/components/README.md for detailed documentation.
Create .env.local based on .env.local.example:
# Stripe (optional - for payments)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Facebook Conversions API (optional - for server-side tracking)
FACEBOOK_CONVERSIONS_API_TOKEN=your-token
# Sentry (optional - for error tracking)
NEXT_PUBLIC_SENTRY_DSN=https://...
# Google Cloud Storage (optional - for webhook backup)
GCS_BUCKET_NAME=your-bucket- Facebook Pixel: Configure in
app/config/facebook.ts - Matomo: See docs/matomo-tracking.md
- Sentry: Configure in
app/config/sentry.ts
All funnels must be responsive across:
| Device | Breakpoint |
|---|---|
| Mobile | 375px+ |
| Tablet | 768px+ |
| Desktop | 1440px+ |
Use Tailwind's responsive utilities (sm:, md:, lg:, xl:) with mobile-first approach.
This project is designed for seamless Vercel deployment with zero configuration:
- Import to Vercel: Go to vercel.com/new and import your GitHub repository
- Auto-detect: Vercel automatically detects Next.js and configures the build
- Environment Variables: Add any required variables in Project Settings → Environment Variables
- Deploy: Push to
mainbranch for production, PRs get automatic preview URLs
No GitHub Actions or CI configuration needed - Vercel handles everything automatically.
npm run build
npm run start- Stripe Webhook Setup
- Payment Testing
- App Redirect & Deep Linking
- Matomo Tracking
- GCS Webhook Storage
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure your code:
- Uses TypeScript with strict typing
- Follows mobile-first responsive design
- Tests on mobile, tablet, and desktop breakpoints
- Updates documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
Built with Next.js and Tailwind CSS by Ozma
