Skip the api/ folder entirely
The standard Vercel recipe is a serverless function plus an email SDK and its API key in your environment variables. A form action replaces all of it. Nothing to write, deploy, or rotate.
integrations · hosting platform
Vercel doesn't ship a built-in form product, so the usual advice is to write a serverless function and wire it to an email API. You can skip all of that: point a plain HTML form at your mailcontact endpoint and submissions land in your project's inbox, with a notification in Discord, Slack, email, or a webhook.
Because it's just a form action, it works with anything you deploy to Vercel: Next.js, Astro, SvelteKit, or a folder of static HTML. Your pages stay static or ISR, there's no function to invoke on submit, and no email provider account to create.
recommended setup
Add this HTML to your site, or use the form builder. Replace the form link with yours. The hosted script injects the hidden check, handles sending and automatic verification, and preserves the draft on errors. You control the HTML and CSS. Free forms display a visible “Processed by mailcontact.app” link; Pro and Plus do not. Feedback follows the browser’s language; set data-mailcontact-language="fr" on the form to force French.
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST" data-mailcontact-form>
<fieldset>
<legend>Contact us</legend>
<label>
Name (optional)
<input name="name" type="text" autocomplete="name" maxlength="200" />
</label>
<label>
Email
<input name="email" type="email" autocomplete="email" maxlength="320" required />
</label>
<label>
Message
<textarea name="message" rows="5" maxlength="5000" required></textarea>
</label>
<noscript>
<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;">
<label>Website
<input name="company_website" type="text" tabindex="-1" autocomplete="off" />
</label>
</div>
</noscript>
<button type="submit">Send message</button>
</fieldset>
<p data-contact-status role="status" aria-live="polite" aria-atomic="true"></p>
</form>
<script defer src="https://mailcontact.app/forms/v1.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>For a component with its own submit handler, load the same script and use MailContact.prepare(form) and MailContact.send() instead of the automatic marker. See the custom interface reference for loading, feedback and Free attribution.
the snippet
This example posts directly to the API. Keep the required company_website field present and empty. Native posts open JSON on success or a verification page when needed. Custom scripts without verification support send suspicious messages to Spam for review; strong spam is also held there without notifications or quota usage. A success response confirms reception, including review, or a silent discard of a filled check. See spam protection for the full behavior.
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST">
<input type="text" name="name" placeholder="Your name" />
<input type="email" name="email" placeholder="[email protected]" required />
<textarea name="message" placeholder="What's on your mind?" required></textarea>
<button type="submit">Send</button>
<input name="company_website" type="text" tabindex="-1" autocomplete="off"
style="position:absolute;left:-10000px" aria-hidden="true" />
</form>how it works
One inbox per project. Name it after your deployment and you get a form endpoint and a project email address immediately.
Paste the form into whatever you deploy to Vercel: a static page, a Next.js component, an Astro template. Push, and Vercel ships it like any other change.
Add a Discord, Slack, email, or webhook channel. Delivered messages ping you where you already are.
why mailcontact
The standard Vercel recipe is a serverless function plus an email SDK and its API key in your environment variables. A form action replaces all of it. Nothing to write, deploy, or rotate.
Submissions post to mailcontact's servers, not your deployment. Contact traffic never counts against your function invocations, and there's no cold start between a visitor and their message.
The endpoint accepts posts from any origin, so the same form works on *.vercel.app preview URLs and your production domain. No per-environment config or env vars.
faq
No. At the time of writing Vercel has no forms product, so the common answer is a serverless function plus an email API. With mailcontact the form posts straight to your project inbox instead, and your site stays static.
Yes. The endpoint accepts cross-origin posts from any URL, so the same snippet works on preview URLs, your production domain, and localhost during development.
Use the hosted MailContact script, or call MailContact.send() in your own handler, and render an inline thank-you. A configurable redirect for native form posts is not currently available.
The endpoint rate-limits to 20 requests per minute per IP with a 64KB max body (generous for a contact form), and it protects your inbox from basic flooding.
related
Forms and a real email address, together, with notifications where you live. Start with a free account.
Create your free formNo credit card needed. Free includes one project and 50 form messages per month.