Give your v0 contact form a working backend.
Keep the interface v0 generated. Form Plume receives every submission, emails it to you, stores it safely, and delivers it to your other tools.
"use client";
const response = await fetch(FORM_ENDPOINT, {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
if (!response.ok) throw new Error("Submission failed");The full guide
From v0 preview to production proof.
Control the client boundary, protect real secrets, and verify the exported application rather than trusting preview alone.
v0 can build full-stack Next.js applications with server actions, route handlers, databases, and integrations. Those are valid tools. For a public contact or waitlist form, a browser-to-Form Plume request can be the smaller path, especially when you want the form to remain portable after exporting the component.
- 1Create your Form Plume accountStart free and give your v0 form a hosted endpoint for email, submissions, spam filtering, uploads, integrations, and webhooks.Start free
- 2Create the form and copy the endpointCopy the endpoint URL from Form Plume. It looks like
https://api.formplume.com/f/your-slug - 3Connect it inside v0Review the generated files, test the v0 preview, then verify the exported application on its production origin. Send one test submission from the real v0 app or preview environment and confirm it reaches Form Plume.
Give v0 a precise prompt
Update the existing contact form without changing its visual design.
Post FormData from the client to this public endpoint:
https://api.formplume.com/f/your-public-slug
Add accessible pending, success, and error states. Keep values after failure and reset
only after a 2xx response. Every submitted control needs a name. Do not create a
server action, route handler, database table, or email-provider integration solely for
this form. Do not put private keys or webhook secrets in NEXT_PUBLIC_ variables.
Explain whether the edited component needs "use client", list changed files, and give
the exact commands to typecheck and build the exported Next.js project.Client component example
"use client";
async function submit(form: HTMLFormElement) {
const response = await fetch("https://api.formplume.com/f/your-public-slug", {
method: "POST",
headers: { Accept: "application/json" },
body: new FormData(form),
});
if (!response.ok) throw new Error("Submission failed");
}Interactive state and event handlers make this a client component in Next.js App Router. Keep the client boundary as low as practical rather than converting an entire page. A NEXT_PUBLIC_ value is bundled for the browser and is not secret; only the public endpoint belongs there.
When the full-stack path wins
Keep a server action or route handler when custom authorization, private API calls, or transactional updates belong in the request. Use the direct endpoint when the job is standard public form intake and introducing a server boundary adds no product value.
Verify after export
- Inspect the diff for needless routes, packages, and broad
"use client"boundaries. - Run the exported repository's actual lint, typecheck, tests, and
next build. - Test success and verify the Form Plume record.
- Test a bad slug and confirm values survive.
- Deploy and retest from the final Vercel or custom-domain origin.
See the deeper Next.js guide and compare Lovable, Bolt, Replit, and Base44.
Primary sources
FAQ
v0 questions
before you export.
One line. Zero backend.
