Next.js waitlist form

Add a waitlist form to your Next.js launch page with no backend. Copy the code, preview it live, and every signup lands in your inbox. Spam is filtered automatically and there is no API route to build.

How to build it

  1. Create a form in your Formpaste dashboard and copy its access key.
  2. Pick your styling and copy the Next.js code into a client component.
  3. Replace YOUR_ACCESS_KEY_HERE with your access key, then deploy.

Prompt for your AI coding agent

Add a Formpaste waitlist signup form to my Next.js app. Use a client component with name and email fields that POSTs as application/x-www-form-urlencoded (URLSearchParams) to https://api.formpaste.com/submit with a hidden access_key input. Show a success state after the fetch resolves. Do not add an API route.

Or connect the Formpaste MCP server to Claude Code, Codex, Cursor, Claude Desktop, VS Code, or any mcp-remote client. See the setup guide.

Next.js gotchas

Next.js gives you API routes, but for simpler forms, spinning up a route handler is overkill. Formpaste handles the backend so you can keep your Next.js app focused on the frontend. Works with both App Router and Pages Router.

Client component for the fetch version

The onSubmit fetch needs to run in the browser, so put the form in a file with "use client" at the top. A plain <form action> with a redirect works in a server component too if you do not need JS.

No API route needed

You do not need /api/contact. Posting straight to the Formpaste endpoint keeps the app static-friendly and deployable anywhere, including static export.

Server Actions are optional

You can wire a Server Action, but it is not required and adds a server round-trip. The direct POST is simpler and works on static hosting.

Edge runtime and file uploads

If a route uses the Edge runtime, multipart form data handling differs from Node. For file-upload forms, post directly to Formpaste from the client so your own runtime never parses the upload.

Static export friendly

Because the form posts to an external endpoint, output: export keeps working. No server code of yours runs at request time.

What to get right

Show a success state

A waitlist signup should confirm instantly. Track state after the submit resolves and swap the form for a You are on the list message.

Referral position is optional

You can add a referral code field later, but do not block the core signup on it. Keep the first version to email plus name.

Deduplicate on your side

The same person may sign up twice. Treat email as the key when you export or sync the list.

How it works

Three simple steps for form submissions to land in your email inbox.
Create your form, set your form's action URL to Formpaste's endpoint, and add your access key.

1

Create your form

Sign up, verify your email, and create an access key in your dashboard.

2

Copy the code

Paste the snippet above into your project. Pick CSS or Tailwind to match your site.

export function ContactForm() {
  async function onSubmit(e) {
    e.preventDefault();
    const form = new FormData(e.currentTarget);
    await fetch("https://api.formpaste.com/submit", { method: "POST", body: new URLSearchParams(form) });
  }

  return (
    <form onSubmit={onSubmit} className="mx-auto flex w-full max-w-md flex-col gap-4 rounded-xl border border-gray-200 bg-white p-6 shadow-sm dark:border-gray-800 dark:bg-gray-950">
      <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY_HERE" />
      <label className="flex flex-col gap-1.5 text-sm font-medium text-gray-900 dark:text-gray-100">Email
    <input type="email" name="email" placeholder="you@example.com" required className="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm outline-none focus-visible:ring-2 focus-visible:ring-gray-900 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus-visible:ring-gray-100" />
  </label>
      <label className="flex flex-col gap-1.5 text-sm font-medium text-gray-900 dark:text-gray-100">Name
    <input type="text" name="name" placeholder="Your name" className="rounded-md border border-gray-300 bg-white px-3 py-2 text-sm text-gray-900 shadow-sm outline-none focus-visible:ring-2 focus-visible:ring-gray-900 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus-visible:ring-gray-100" />
  </label>
      <button type="submit" className="w-full rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-white shadow-sm transition-colors hover:bg-gray-800 disabled:opacity-60 dark:bg-white dark:text-gray-900 dark:hover:bg-gray-200">Join the waitlist</button>
    </form>
  );
}
3

Add your access key

Replace the placeholder with your access key to start receiving submissions.

<input type="hidden" name="access_key" value="YOUR_ACCESS_KEY_HERE">

Next.js waitlist form FAQ

Paste a form. Get submissions.

Instantly without setting up any backend, servers or databases. 250 submissions/mo free - no credit card.

Other Next.js forms