Add a Contact Form to an AI-Built App That Works
An AI tool will draw a contact form in one prompt. What it often leaves out is everything that happens after Send: validation, spam, storage and a confirmation that the message arrived.
To add a contact form to an AI-built app, ask for five things, not one: the fields, checks that run on the server, a spam guard, a database row saved before any email is sent, and a clear confirmation for the visitor. Most generated forms deliver only the first and the last, which is why they look finished and quietly lose messages.
This guide walks through each part, shows what to check in the generated code, and ends with a prompt you can paste into your builder.
What it takes to add a contact form to an AI-built app
A contact form looks like three inputs and a button. In practice it is a small pipeline: a visitor types, your server accepts or rejects, you keep a record, someone gets told, and the visitor sees what happened. Any weak link means a lost lead that you never knew existed. If you are still assembling the app itself, start with how to build an app with AI and come back for this part.
When you add a contact form to an AI-built app, the model draws the visible part first. The pipeline behind it is where the gaps are.
Part 1: the fields, and why fewer is better
Name, email and message cover almost every case. If you need a longer form with many questions, that is a different job, covered in building a client intake form with AI. A phone field is worth adding only if you will actually call people. Every extra field costs completions, and you can always ask a follow-up question by reply.
Two small details are easy to miss in generated code:
Use the right input type,
type="email"for the address, so mobile keyboards show the @ key.Set
autocompletevalues so browsers can fill the form. The MDN documentation on the autocomplete attribute listsnamefor a full name andemailfor an address, and notes that valid tokens help people with motor or cognitive difficulties fill forms faster.
<form method="post" action="/api/contact">
<label for="name">Name</label>
<input id="name" name="name" type="text" autocomplete="name" required>
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" required></textarea>
<button type="submit">Send message</button>
</form>Every input needs a visible label tied to it with for and id. Placeholder text alone disappears as soon as the visitor starts typing.
Part 2: checks that run on the server
Browser validation is a courtesy. Anyone can send a request straight to your endpoint and skip it, so the server has to check again. Ask for these rules:
Reject empty or whitespace-only fields.
Cap the length of each field, for example 200 characters for the name and 5,000 for the message.
Check the email has a plausible shape, then stop. Do not try to prove an address is real with a clever pattern.
Return a clear error the form can show next to the field that failed.
A generated handler that does insert(req.body) with no checks is the most common problem. It lets anyone fill your table with anything.
Part 3: a spam guard that costs real people nothing
A public form gets automated submissions quickly. Three cheap measures, in order of how little they bother visitors:
A honeypot field. An extra input hidden with CSS that people never see. If it arrives filled in, the sender was a script, so you discard the message and still return a success page.
A rate limit. Allow a handful of submissions per IP address per hour.
A minimum fill time. Store a timestamp when the form loads and reject anything submitted within two seconds.
Reach for a CAPTCHA only if these are not enough. It adds friction for every real visitor.
Part 4: save first, then send the email
This is the rule that saves the most messages. Write the submission to a database table first, then try to send the notification email. If the email provider is down, the message still exists and you can resend it.
A table with id, name, email, message, created_at and a notified boolean is enough. The email step flips notified to true when it succeeds. A short scheduled job can retry any row where it is still false.
Keep the email provider's API key in an environment variable on the server, never in front-end code. The same care applies as for any secret, covered in keeping secrets out of an AI-built app. And if the notification mail itself goes missing, see why emails from an AI-built app go to spam.
Part 5: tell the visitor what happened
The form should reply in one of three ways: a thank-you message that says when to expect an answer, a field-level error they can fix, or a plain "something went wrong, please email us at this address" that gives them another route. Disable the button after the first click so a double click does not send two copies.
The prompt to paste
Add a contact form to this app with name, email and message.
Requirements:
- Server-side validation: required fields, max lengths (name 200, message 5000), basic email shape.
- Honeypot field and a per-IP rate limit of 5 submissions per hour.
- Save every submission to a contact_messages table BEFORE sending any email.
- Send a notification email through the existing email provider; mark the row notified only on success.
- Show a thank-you state on success and field-level errors on failure; disable the button while sending.
- Use autocomplete="name" and autocomplete="email"; label every input.
Do not put any API key in client code.Afterwards, test it yourself: submit an empty form, a 10,000-character message and a normal one, then check the table. If the empty form creates a row, the server checks are missing.
For a form where outside suppliers submit their details, see adding a vendor onboarding form to an AI-built app.
Frequently asked questions
Do I need a backend to add a contact form to a website?
Something has to receive the submission and keep or forward it. That can be your own server route, a serverless function or a hosted form service, but a form that only posts to nowhere stores nothing.
Should the form send email directly or save to a database first?
Save first. The database row is your record, and the email is only a notification. If email fails, you still have the message.
How do I stop spam on a contact form without a CAPTCHA?
Combine a hidden honeypot field, a rate limit per IP address and a minimum time between page load and submission. Add a CAPTCHA only if spam continues.
What happens if my AI tool wrote the form with no validation?
Ask it to add server-side checks for required fields, length limits and email shape. Then test with an empty submission to confirm the server rejects it.
How did this land?
About the author

Developer Advocate
Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.


