Next.js
Next.js contact form that sends email without an API route
Most Next.js contact form tutorials end with an API route, an email library and a secret in your environment. Heartdove removes all three: a client component posts to the Heartdove endpoint, the submission is stored first, and the email alert is tracked until it is delivered or bounced.
Updated 20 October 2026
Add the form to Next.js
In the App Router, put the form in a client component (the file starts with "use client") and render it from any page. In the Pages Router, the same component works in a page file. No route handler, server action or email package is needed.
'use client';
import { createClient, readForm } from '@heartdove/forms';
import { useFormSubmit } from '@heartdove/forms/react';
const client = createClient({
endpoint: 'https://submit.heartdove.com/v1/submit',
accessKey: 'YOUR_ACCESS_KEY',
});
export function ContactForm() {
const { state, submit } = useFormSubmit(client);
return (
<form onSubmit={e => { e.preventDefault(); submit(readForm(e.currentTarget).fields); }}>
<label>Email <input name="email" type="email" required /></label>
<label>Message <textarea name="message" required /></label>
<input type="checkbox" name="botcheck" tabIndex={-1} autoComplete="off" style={{ display: 'none' }} />
<button disabled={state.phase === 'submitting'}>
{state.phase === 'sent' ? 'Sent' : 'Send message'}
</button>
</form>
);
}The hook is the React adapter, which has been tested in a real browser. The Next.js wrapper around it has not been separately tested; it is a plain client component.
Preview deployments get their own origin. Register the production address and any preview address you want to test from; each form accepts up to 10 exact origins.
Register your website address
Heartdove accepts a submission only from the exact website addresses registered on the form, so a copied key cannot be fired from somewhere else. Register every address the form is published on; each form takes up to 10, and registering a www address covers the bare domain too. For a Next.js site that usually means:
https://www.yourdomain.comhttps://your-app.vercel.apphttp://localhost:3000
Testing locally? Register your local address, such as http://localhost:3000, as well.
What happens after submit
The message is saved to your inbox before any email is sent, so a failed alert never loses the enquiry. The alert is then tracked step by step and shown on the message:
- CapturedSaved and searchable
- Accepted by providerHanded to the email provider
- DeliveredThe recipient’s mail server accepted it
- BouncedShown with the reason; the address is paused
Over your monthly allowance, submissions are held, visibly, and released automatically. Nothing is billed as overage, and each plan’s hold capacity is on the pricing page. The Free plan includes 500 submissions a month with an instant alert for each.
Spam, without a CAPTCHA
Every form gets the exact origin check, a per-visitor rate limit, the hidden trap field and spam scoring with quarantine. Cloudflare Turnstile can be turned on per form for a human check, and is never required. Read how the layers work.
Questions
Do I still need a server action or API route?
No. The browser posts straight to Heartdove. If you prefer to keep the request on the server, a route handler can post the same JSON with fetch.
Is it safe to put the access key in my page?
Yes. The key is public and only identifies the form; it does not grant access to anything. Submissions are accepted only from the website addresses you register, each visitor is rate limited, and every message is scored for spam before it is stored.
Do I need a CAPTCHA?
No. Every form gets an exact origin check, a per-visitor rate limit, a hidden trap field and spam scoring with quarantine. Cloudflare Turnstile is optional for forms that want a human check.
What happens if I go over the free limit?
Submissions above your monthly allowance are held, visibly, for at least seven days and released automatically when your allowance resets. Each plan’s hold capacity is on the pricing page, and there is no overage charge.
Never lose another enquiry.
Connect your first form in a few minutes. Your existing design stays exactly as it is.