At a glance
- Output
- Next.js
- API route
- Not needed
- Submit
- Server Action or fetch
- Where it goes
app/contact/actions.ts- Database
- None
The integration
v0 output lands in Next.js. This Server Action forwards the submission to your endpoint: no /api route, no database. A plain client-side fetch works too if the form is a client component.
Wire the contact form in this v0 / Next.js project to this MakeTheForm endpoint:
https://mtform.co/f/your-form-key
Requirements:
- Prefer a Server Action that forwards the fields to the endpoint via fetch as JSON. Do NOT create a database or a custom /api route beyond the action itself.
- Keep the existing shadcn/ui markup and styling. Only add submit wiring.
- Disable the submit button while pending (useActionState / pending state).
- Treat any HTTP 2xx as success: show an inline success message and reset the form.
- On error, surface the JSON response’s error.message and keep the user’s input.
- Include a hidden honeypot input named exactly "_mtf_honeypot" (position:absolute;left:-9999px, tabIndex={-1}, autoComplete="off", aria-hidden="true"). Never display:none, never required.
- The endpoint URL is public and safe in client code. Do NOT invent or request an API key.Step by step
- 1
Create the endpoint
Create a MakeTheForm form to get your endpoint URL and inbox.
- 2
Generate in v0, then wire it
Keep your v0-generated form and paste the prompt above. It adds a Server Action (or fetch) that forwards to your endpoint.
- 3
Verify and ship
Verify the recipient once, deploy to Vercel, and submit to confirm the inbox and email delivery.
Common pitfalls
Building a full /api route + Resend
v0 will offer to add a route handler and an email SDK. That’s a mail integration and a deliverability reputation to manage. Forwarding from a one-line Server Action to the endpoint avoids all of it.
Client component vs Server Action mismatch
If the form is a client component, a Server Action still works when imported, but a plain fetch is simpler. Don’t mix a "use server" action into a "use client" file directly, import it.
Troubleshooting
| Symptom | What’s happening | Fix |
|---|---|---|
| action not firing | The form uses onSubmit instead of the Server Action’s action prop. | Bind the action to <form action={...}> or call the action from your submit handler. |
| 422 | The POST arrived with no fields at all (reserved _mtf_ fields do not count). | Give every input a name attribute: the browser never sends an input without one. With fetch, check the body is FormData or JSON built from the form, not empty. |
Frequently asked questions
Does v0 handle form submissions?
v0 generates the form UI (usually shadcn/ui) but not a backend. To actually receive submissions you either add server code or point the form at a hosted endpoint: the endpoint handles email, spam, and storage for you.
Should I use a Server Action or a client fetch?
Either works. A Server Action keeps the endpoint call server-side and pairs well with useActionState for pending UI; a client fetch is the least code. Both forward to the same endpoint.
Do I need a database for a v0 form?
No. The endpoint stores each submission in a searchable, exportable inbox, so a contact or lead form needs no database of your own.
Other platforms
Keep going
Last reviewed by the MakeTheForm team.