You spent three months building your SaaS. You launched. Nobody showed up.
That is the most common story in indie hacking, and the fix is not a better product -- it is a waitlist page you put up before you write a single line of backend code.
A pre-launch waitlist does three things: it confirms people actually want what you are making, it gives you a warm audience to email on launch day, and it creates early social proof. None of those require your product to exist yet.
Here is how to build one in a Next.js app using the tools that ship with the boilerplate, and why getting this right before launch matters more than most founders realize.
The typical launch goes like this: post on Product Hunt, share on Twitter, tell three friends, wait. The first hour is quiet. By evening you have twelve signups, six of them are the founder's contacts, and two are bots.
The pattern repeats because the audience was not built. A waitlist page -- even a single email capture field on a plain page -- starts building that audience weeks or months before you ship.
If you want to know whether an idea is worth building before you commit to it, read how to validate your SaaS idea before writing a single line of code. But once you have validated the idea, a waitlist is how you turn that validation into launch momentum.
Keep it simple. A waitlist page needs:
Nothing else. No pricing table, no feature grid, no lengthy explainer. The person submitting their email is making a small bet that your product will be worth their attention. Make it easy to bet.
The Next.js SaaS Boilerplate ships Resend for transactional email and Drizzle ORM with Neon DB for data. Those three tools are everything a waitlist needs.
Database schema
Store each waitlist entry with a unique referral code and a counter tracking how many people joined through their link:
waitlist_entries
id uuid, primary key
email text, unique, not null
referral_code text, unique, not null
referred_by text (referral code of the referrer)
referral_count integer, default 0
created_at timestamp
One table. No user account required -- visitors sign up before they have an account.
The API route
Your POST /api/waitlist route does four things: validate the email with Zod, check for duplicates, generate a unique referral code and store the entry, then send a confirmation email via Resend that includes the referral link.
// modules/waitlist/waitlist.service.ts
export async function joinWaitlist(email: string, referredBy?: string) {
const existing = await waitlistRepo.findByEmail(email);
if (existing) throw new HttpError(409, 'Already on the waitlist');
const code = nanoid(8); // short, URL-safe code
await waitlistRepo.create({ email, referralCode: code, referredBy });
if (referredBy) {
await waitlistRepo.incrementReferralCount(referredBy);
}
await emailService.sendEmail({
to: email,
subject: "You're on the list",
react: React.createElement(WaitlistConfirmEmail, {
referralLink: `${process.env.NEXT_PUBLIC_BASE_URL}/?ref=${code}`,
}),
});
}
The service follows the same pattern as the rest of the boilerplate -- validation in the route, business logic in the service, DB access in the repo. See the docs for how the module structure is set up.
The referral loop
Every confirmation email includes a personal referral link. When someone signs up through that link, the original person moves up the list or unlocks early access. This is how waitlists like Superhuman and Robinhood grew without any ad spend: the act of signing up creates a reason to share.
You do not need gamification or a leaderboard. A single line in the confirmation email -- "Share your link and get early access when three friends join" -- is enough to motivate early adopters.
The waitlist page is a Server Component with a single client form. No auth check, no session. The form submits to /api/waitlist, shows a success message, and optionally displays the referral link inline after submission.
Keep the copy tight. The best waitlist pages are under 100 words above the fold. A structure that works:
When you are ready to ship, you have a warm list of people who opted in. Send one plain email -- not a campaign -- that says the product is live and links to it. Then watch which segment converts.
People who referred friends convert at two to three times the rate of people who found the page on their own. That is your early adopter signal: they cared enough to share, which means they care enough to pay.
For what comes after the launch, the Product Hunt launch checklist walks through the 30-day sequence that gets real signups on launch day.
Waitlist infrastructure is less than a day of work when you are not also building auth, email, and a database from scratch. The boilerplate has all three ready -- you add the waitlist schema and page, and the hard parts are already handled.
Get the Next.js SaaS Boilerplate and have your waitlist page live before the weekend is over.