A modern, real-time waitlist landing page template for MVP validation. Built with Next.js and Supabase.
- Landing Page - Clean, modern design with product name, slogan, and features showcase
- One-Click Join - Users can join the waitlist with a single click after signing in
- Real-time Updates - Live counter showing the number of people on the waitlist (powered by Supabase Realtime)
- Queue Position - Users can see their position in the waitlist
- Public Stats Page -
/adminpage showing waitlist statistics (total, today, this week, this month) - Privacy Protection - Email addresses are partially masked in the public stats page
- Dark Mode - Built-in theme switcher for light/dark mode
- Responsive Design - Works on desktop, tablet, and mobile devices
- Framework: Next.js (App Router)
- Language: TypeScript
- Backend: Supabase (PostgreSQL + Auth + Realtime)
- Styling: Tailwind CSS
- UI Components: shadcn/ui + Radix UI
- Icons: Lucide React
- Node.js 18+
- A Supabase project (create one here)
-
Clone the repository
git clone <your-repo-url> cd waiting-list
-
Install dependencies
npm install
-
Set up environment variables
Create a
.env.localfile in the root directory:NEXT_PUBLIC_SUPABASE_URL=your-supabase-project-url NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-supabase-anon-key
You can find these values in your Supabase project settings.
-
Set up the database
Go to your Supabase Dashboard → SQL Editor, then copy and paste the contents of
supabase/init.sqland run it.This will create:
waitlist_entriestable- Row Level Security (RLS) policies
- Database functions for the waitlist logic
- Supabase Realtime configuration
-
Run the development server
npm run dev
-
Open http://localhost:3000 in your browser
├── app/
│ ├── page.tsx # Landing page
│ ├── admin/page.tsx # Public stats page
│ └── auth/ # Authentication pages
├── components/
│ ├── hero.tsx # Hero section
│ ├── features.tsx # Features showcase
│ ├── join-waitlist-button.tsx # Join button with state handling
│ ├── waitlist-stats.tsx # Real-time counter
│ └── ui/ # shadcn/ui components
├── lib/
│ ├── supabase/ # Supabase client configuration
│ └── types/database.ts # TypeScript types
└── openspec/ # OpenSpec documentation
The project uses a single table waitlist_entries:
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| user_id | UUID | Reference to auth.users |
| queue_position | INTEGER | Position in the waitlist |
| joined_at | TIMESTAMPTZ | When the user joined |
Edit components/hero.tsx to change the product name and slogan.
Edit components/features.tsx to customize the feature cards.
The project uses Tailwind CSS with CSS variables for theming. Edit app/globals.css to customize colors.
- Push your code to GitHub
- Import the project in Vercel
- Add your environment variables
- Deploy
The project can be deployed to any platform that supports Next.js (Netlify, Railway, etc.).
MIT