Vibe Code a Waitlist Page That Actually Captures Emails

Build a working waitlist in an hour — with the double-submit, spam, and deliverability problems AI leaves in by default.

C
CodeIllusion Team
#vibe-coding #waitlist #tutorial #saas #marketing
Vibe Code a Waitlist Page That Actually Captures Emails

The simplest genuinely useful thing you can build. One input, one table, one email — and four ways it silently doesn’t work.

The Build

Next.js App Router, TypeScript, Tailwind, Supabase. Build a waitlist landing page.

Hero with headline, one-sentence description, and an email capture form. Below: three benefit points and an FAQ.

Create a waitlist table: id uuid, email citext unique not null, referrer text, utm_source text, created_at timestamptz, confirmed boolean default false.

The form must submit to a server action that validates the email server-side, inserts it, and returns a real success or error state. Don’t stub the handler — I want a working database write.

That last sentence is there because the default behaviour is a stub. You’ll get a form with a spinner, a success message, and nothing in your database.

Test it immediately. Submit your own address, then check the table. Don’t move on until you see the row.

The Four Things It Gets Wrong

1. Duplicate submissions

Someone signs up twice, or double-clicks. Without handling, you get either a database error shown as a scary red message, or two rows.

Handle duplicates gracefully. On a unique violation, return the same success message as a new signup — don’t reveal whether the address was already on the list. Disable the submit button while the request is in flight.

Not revealing existing addresses matters more than it seems: a waitlist that says “already registered” is an email enumeration tool.

2. No spam protection

An open form on a public page will get bot submissions within days.

Add a honeypot field — a hidden input bots fill and humans don’t. Silently discard any submission where it’s non-empty, returning success so bots don’t learn. Add rate limiting of 3 submissions per IP per hour.

Honeypots cost nothing and catch most low-effort bots. Add Turnstile only if you actually see abuse — it adds friction for real users.

3. Email that goes to spam

Sending from your app server directly means poor deliverability from day one.

Send a confirmation email via Resend when someone joins. Include their position on the list. Send from a subdomain like updates@yourdomain.com, not the root domain. Give me the SPF, DKIM and DMARC records I need to add.

Set up the DNS records before launch. Deliverability reputation builds over time, and starting cold on launch day is how a waitlist announcement lands in spam.

4. No attribution

If you don’t capture where signups came from, you can’t tell which channel worked.

Capture the referrer and any UTM parameters from the URL and store them with each signup. Add an admin page at /admin/waitlist showing total signups, signups per day, and a breakdown by source. Protect it — it must not be publicly accessible.

That last clause matters. An unprotected admin route lists everyone’s email address.

Position Numbers and Referrals

Showing someone they’re “#347” measurably improves sharing. Referral mechanics amplify it further.

Add a referral system. Each signup gets a unique code. Signing up with someone’s code moves the referrer up the list. Show the user their position and a shareable link with pre-filled share text.

One caution: don’t compute position by counting rows on every page load. It’s a full table scan on your most-hit endpoint.

Store position as a column assigned at insert. Don’t compute it with a count query on read.

Before Launch

  • Real submission tested end to end — row exists in the database
  • Confirmation email received, checked in Gmail and Outlook
  • SPF, DKIM, DMARC configured and verified
  • Duplicate submission returns success, not an error
  • Honeypot present and working
  • Rate limiting active
  • Admin page requires authentication
  • UTM parameters captured
  • Mobile tested on a real device
  • Privacy policy linked (you’re collecting personal data)

That last one is a legal requirement in most jurisdictions once you store email addresses, and it’s the sort of thing AI never adds unasked.

Export Before You Need It

Write the export now, while you remember the schema:

Add an admin-only CSV export of the waitlist with email, signup date, source, and referral code.

Launch day is a bad time to discover you can’t get your list out.

Next

A waitlist is the front of a product that doesn’t exist yet. When it does, vibe code a landing page covers the real marketing page, and vibe code a SaaS MVP covers what those emails eventually get invited to.

Related reading:

Frequently Asked Questions

How do I build a waitlist page quickly? +

A landing page with an email form, a database table, and a confirmation email is an hour's work with AI tools. The parts that need explicit requests are duplicate handling, spam protection, and a real email destination — none of which affect whether the form appears to work.

Why do AI-generated forms not save anything? +

AI often stubs the submit handler with a console log or a fake delay, because that makes the UI work without needing a backend. It looks completely functional. Always test with a real submission and check the database.

How do I stop bots signing up to my waitlist? +

A honeypot field catches most basic bots for free. Add rate limiting per IP, and Cloudflare Turnstile if you're getting real abuse. Ask for all three explicitly — AI doesn't add them by default.

Should I send a confirmation email to waitlist signups? +

Yes. It confirms the address is real, sets expectations, and gives you a deliverability signal before launch day. Use Resend or Postmark — sending directly from your app server means going straight to spam.

Tagged:

#vibe-coding #waitlist #tutorial #saas #marketing

Enjoyed this article?

Get more AI tool picks, coding tutorials, and no-code automation guides every week. No spam, ever.

Found this useful? Share it:

More in No-Code & Low-Code AI