Waitlist System

Collect early interest and build your audience before launch.

Features

  • • Email validation
  • • Duplicate prevention
  • • Admin dashboard
  • • Export functionality

Use Cases

  • • Pre-launch collection
  • • Early access management
  • • Beta testing
  • • Marketing campaigns

Database Schema

prisma/schema.prisma
1model WaitlistEntry {
2 id String @id @default(cuid())
3 email String @unique
4 isActive Boolean @default(true)
5 createdAt DateTime @default(now())
6 updatedAt DateTime @updatedAt
7}

Server Actions

src/server/actions/waitlist.ts
1"use server";
2
3import { db } from "~/server/db";
4import { z } from "zod";
5
6const schema = z.object({
7 email: z.string().email("Please enter a valid email"),
8});
9
10export async function addToWaitlist(formData: FormData) {
11 const email = formData.get("email") as string;
12 const { email: validEmail } = schema.parse({ email });
13
14 const existing = await db.waitlistEntry.findUnique({
15 where: { email: validEmail },
16 });
17
18 if (existing) {
19 return { success: false, error: "Already on the waitlist!" };
20 }
21
22 await db.waitlistEntry.create({
23 data: { email: validEmail, isActive: true },
24 });
25
26 return { success: true, message: "Successfully added!" };
27}

Signup Form

src/components/WaitlistSignup.tsx
1"use client";
2
3import { useState } from "react";
4import { addToWaitlist } from "~/server/actions/waitlist";
5
6export function WaitlistSignup() {
7 const [message, setMessage] = useState("");
8 const [isLoading, setIsLoading] = useState(false);
9
10 async function handleSubmit(formData: FormData) {
11 setIsLoading(true);
12 const result = await addToWaitlist(formData);
13 setMessage(result.success ? result.message : result.error);
14 setIsLoading(false);
15 }
16
17 return (
18 <form action={handleSubmit} className="flex gap-2">
19 <input
20 type="email"
21 name="email"
22 placeholder="Enter your email"
23 required
24 className="flex-1 rounded-md border px-3 py-2"
25 />
26 <button type="submit" disabled={isLoading}>
27 {isLoading ? "Joining..." : "Join Waitlist"}
28 </button>
29 </form>
30 );
31}

Best Practices

Growth

  • • Add social proof (member count)
  • • Offer exclusive benefits
  • • Create referral incentives
  • • Share behind-the-scenes

Engagement

  • • Send welcome emails
  • • Share development progress
  • • Ask for feedback
  • • Provide early access perks

Next: Admin Panel

User and subscription management

Continue →