Until now, everything you built has been one-way: you write, visitors read. A form flips the direction. Someone on the other side of the internet types a message and — if you wire it up right — it lands in your database and pings your inbox thirty seconds later. This lesson is where your site stops being a brochure and starts being an app.
Part 1 · Why forms change everything
A working form is the smallest possible version of a "backend". You need somewhere to store what the visitor typed, some way to tell you it arrived, and enough guardrails that the form doesn't get abused. Get those three right on a contact form and you've got the mental model for every future feature — signups, bookings, orders, comments.
Part 2 · Anatomy of a working form
Every real form has six pieces. Miss one and it either annoys users or quietly drops data. Name them in your prompt and the agent will build all six.
- 1Fields
Name, email, message — labeled, placeholder text, correct input types.
- 2Validate
Required, real email, length limits. Show errors inline.
- 3Submit
Disable button, show loading, prevent double-send.
- 4Store
Write a row to the database with a timestamp.
- 5Notify
Email you (or Slack, or admin dashboard).
- 6Feedback
Success message or clear recovery on error.
Part 3 · Building the contact form
A good contact-form prompt names all six pieces. You don't have to know the code — you just have to be specific about the behavior.
"Add a contact form to /contact with three fields — name, email, and message. Required, real email, message between 10 and 1000 characters. Show inline errors. On submit, disable the button, save to Lovable Cloud, and show a success card that thanks them by name. If the save fails, keep their text and show a retry."Small things that make a big difference
- Use the right input types:
type="email"triggers the email keyboard on phones. - Label every field. Placeholder text is not a label.
- Disable the submit button while sending — otherwise people click twice and you get duplicates.
- Keep the user's text on error. Never clear a form the visitor just spent a minute filling in.
Part 4 · Saving to Lovable Cloud
The agent handles the wiring, but you should know the shape. A contact submission becomes a row in a table — say contact_submissions — with a column for each field, plus an auto created_at timestamp.
| id | name | message | created_at | |
|---|---|---|---|---|
| a1f0… | Sarah Lee | sarah@studio.co | Interested in a workshop for our team… | 2026-07-19 09:42 |
| c2d3… | Ahmad R. | ahmad@utm.my | Collaboration on NexScholar research… | 2026-07-19 11:08 |
Row-level security — even here
A contact form feels harmless, but the same table might one day hold phone numbers or private notes. Turn on row-level security from day one and be explicit: anyone can insert, only I can read.
Allow anonymous visitors to INSERT into contact_submissions but never SELECT.Only authenticated admins can read submissions in the admin dashboard.Reject inserts where message is empty or over 2000 characters at the database level.
Part 5 · Getting notified
A submission sitting in a database no one checks is worse than no form at all — the visitor thinks you got it, and you didn't. You need at least one notification channel from day one.
Prompts that wire notifications
When a new contact_submissions row is inserted, send me an email at ahmadnajmi.an@utm.my with the visitor's name, email, and message.Add a Contact tab in the admin dashboard that lists submissions newest-first with a "reply" mailto link.Mark a submission as read when I open its detail view so unread ones are easy to spot.
Part 6 · Spam, abuse & trust
The moment your form is public, bots find it. Not eventually — within hours. You don't need enterprise anti-fraud on day one, but you do need two boring defaults: a honeypot field and a rate limit.
Prompts that harden the form
Add a hidden honeypot field called "website" to the contact form. Reject the submission on the server if it's filled.Rate limit contact submissions to 5 per IP per minute using Lovable Cloud.Never trust the client — re-validate name, email, and message length on the server before inserting.
Forms cheat sheet
Six moves that turn a form from "looks like a form" into one you can actually rely on.
- Name the six pieces — fields, validate, submit, store, notify, feedback. Every prompt hits all six.
- Design the success state — a form without a good "thanks" screen doesn't feel finished.
- Validate twice — browser for UX, database for truth. Same rules in both places.
- RLS from day one — insert-only for visitors, read-only for you. Never public SELECT.
- Notify immediately — email or Slack the moment a row lands. Dashboards are the archive, not the alert.
- Honeypot + rate limit — the two boring defaults that keep bots out without hurting real visitors.
Sign up with my invite link and Lovable will drop 10 bonus credits into your account — enough to try everything in this course.
Claim 10 credits