Blog / Technical Guides
Lovable Contact Form Not Sending Email? Get Notified Without a Paid Tool
By Keyona Meeks, Founder, ReRev Labs · Oct 31, 2026 · 9 min read
The short answer: A form on a website page cannot send email by itself. Something has to receive the submission and send the message. If your Lovable contact form looks fine but nothing reaches your inbox, there may be nothing on the other end. One free option is a small Google Apps Script web app: the form posts to it, and it emails you once per valid submission, ignores a hidden spam field and stops when your daily email quota runs low. I tested the script with a mock, not in Google. I could not read Lovable's documentation, so I do not say how Lovable forms work. We sell build work, so weigh this with that in mind.
By the end of this post, you'll be able to:
- Explain why a form can look fine and send nothing.
- Set up a script that emails you on each submission.
- Add basic guards against spam and quota trouble.
- Test the whole path before you trust it.
I sell build work. This post is about notification only: getting an email when someone fills in your form. Storing the submissions is a separate job.
Why does the form send nothing?
My explanation, not a Lovable fact: a form is a set of boxes in a page. When someone presses Submit, the page has to send the answers somewhere. If that "somewhere" is missing, or points at a service that is not set up, the visitor sees a thank-you message and you see nothing. The page cannot email you, because a web page has no mail server.
I could not read Lovable's documentation, so I do not know what it sets up for you. Check what your form actually posts to. Ask Lovable, or whoever edits your site's code, where the submit button sends the data.
What does the script do?
It receives a form post and sends you one email. Specifically:
- It reads the name, email and message fields.
- If a hidden field called
websitehas anything in it, it does nothing and says OK. Real people never see that field. Simple spam bots often fill every field. - It rejects a missing name, a message that is empty or over 2,000 characters, and an email that does not look like an email.
- It removes line breaks from the name, so nobody can slip extra lines into your email subject.
- It checks how many emails you can still send today and pauses when fewer than 10 remain.
- It sends the email to the address you paste in, and replies with a short word: ok, invalid, too long, busy, paused or error.
The limits (2,000 characters, 100 for the name, 10 left in the quota) are my choices.
What does Google's documentation say?
I read these lines for an earlier post and they were verified later, so I reuse them, labeled per an earlier review. Check the live pages.
From the web apps guide: a web app is a script that "contains a doGet or doPost function." It says "When a program sends the app an HTTP POST request, Apps Script runs doPost instead." The event object's e.parameter is "An object of key/value pairs that correspond to the request parameters." And "the script always executes as you, the owner of the script, no matter who accesses the web app."
From the MailApp page: sendEmail "Sends an email message." and getRemainingDailyQuota "Returns the number of recipients you can send emails to for the rest of the day."
The email limits, per an earlier review: 100 recipients a day for consumer accounts and 1,500 for Workspace accounts. The quotas page also says "All quotas are subject to elimination, reduction, or change at any time, without notice."
The "executes as you" line matters. The script sends mail from your account, and anyone who can reach the web app address can trigger it. That is why the guards exist.
What I could not confirm: the "who has access" choices for a web app and where you set them, the menu path to deploy one, and how a browser handles the reply. I did not read the page that describes the manifest. Use Google's current guide.
What is the script?
// Web app that emails you when a website contact form is submitted.
// Paste your own address below. Nothing is stored; one email is sent per valid submission.
const NOTIFY_TO = 'you@example.com';
const MAX_MESSAGE = 2000;
const MAX_NAME = 100;
const MIN_QUOTA_LEFT = 10;
function doPost(e) {
const p = (e && e.parameter) || {};
if (p.website) { return reply_('ok'); }
const name = clean_(p.name, MAX_NAME);
const email = clean_(p.email, 200);
const message = String(p.message || '').trim();
if (!name || !isEmail_(email) || !message) { return reply_('invalid'); }
if (message.length > MAX_MESSAGE) { return reply_('too long'); }
const lock = LockService.getScriptLock();
if (!lock.tryLock(10000)) { return reply_('busy'); }
try {
if (MailApp.getRemainingDailyQuota() < MIN_QUOTA_LEFT) { return reply_('paused'); }
MailApp.sendEmail(NOTIFY_TO, 'Website contact: ' + name,
'Name: ' + name + '\nEmail: ' + email + '\n\n' + message);
return reply_('ok');
} catch (err) {
console.error('Contact form send failed: ' + err.message);
return reply_('error');
} finally {
lock.releaseLock();
}
}
function clean_(v, max) {
return String(v || '').replace(/[\r\n]+/g, ' ').trim().slice(0, max);
}
function isEmail_(s) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s);
}
function reply_(text) {
return ContentService.createTextOutput(text);
}
function testSend() {
const out = doPost({ parameter: { name: 'Test', email: 'test@example.com', message: 'Test message' } });
console.log(out.getContent());
}
I put the sender's email in the body and not in a reply-to header, because I did not confirm the options on sendEmail beyond the line quoted above. You copy the address from the email.
What does the form look like?
A plain HTML form that posts to your web app's address:
<form method="POST" action="YOUR_WEB_APP_ADDRESS">
<input name="name" required>
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<input name="website" tabindex="-1" autocomplete="off" style="display:none">
<button type="submit">Send</button>
</form>
A plain post avoids a problem I expect but did not test: when a page uses JavaScript to send the data, the browser may refuse to let the page read the reply. After a plain post, the visitor sees the one-word reply on a new page, which is not pretty. Test it. If you want a nicer thank-you page, that is a design job for later.
To use this in Lovable, ask it to make the contact form post those four fields to your address. I did not test that.
How do you test the path?
- Paste your address into
NOTIFY_TO. Save. - Run
testSendonce from the editor and approve the permissions. Read the list before you approve. Google says scopes are "determined automatically by scanning the script code," per an earlier review. - Check your inbox for the test email.
- Deploy it as a web app, following Google's current guide, and copy the address.
- Put the address in the form and submit a real test from the live site.
- Submit with the hidden field filled, using the browser's developer tools. No email should arrive.
- Submit with a blank message and a bad email. No email should arrive.
- Delete the test emails.
What did my test cover?
I tested the script with a Node harness that stands in for Google's services, and checked its syntax with node --check on a copy. 24 checks passed. They covered: a valid post sends one email to the right address with all three fields; a filled hidden field sends nothing and still replies ok; a missing name, a bad email, a blank message, and missing or undefined input are rejected with nothing sent; a message over 2,000 characters is rejected; line breaks in the name cannot reach the subject; a low quota pauses and releases the lock; a busy lock sends nothing; a failed send is logged, replies error, and releases the lock; and a long name is cut short.
That checks my logic against my assumptions about Google. I did not run it in Google, and I did not test any form on a real site.
Who should get the email?
You decide. The address is a paste value. Some teams copy a sales lead or an assistant, and others do not want that. Ask the people involved before you add anyone, and do not assume.
What about privacy?
The form collects names and email addresses, and the email carries them. Tell visitors what you do with their details. What the law requires of you depends on where your visitors are. Ask your attorney. I am not one and I give no rule here.
Where does an LLM fit in this?
An LLM can help with the messy part: reading incoming messages and suggesting which are sales questions and which are spam, or drafting a reply for a person to edit. A person should read and send every reply. The script, the guards and the quota check are plain rules, and they do the same thing every time. My stance: AI writes the code, plain automation runs it, and an LLM shows up only where the input is messy and a person checks the result. If you use MailerLite or a similar embed on a Lovable site, see our post on the MailerLite and Lovable trap.
Where this has limits
- I could not read Lovable's documentation. I do not say how its forms work.
- The script was mock-tested, not run in Google. I did not test any form on a real site.
- The Google lines are from an earlier review. Check the live pages.
- I could not confirm the web app access choices, the deploy path or the browser behavior after a post.
- A hidden field stops simple bots only. It will not stop a determined sender, and anyone with the address can post to it.
- Email is not a record. The script stores nothing. If you need a list of submissions, that is a separate build.
- Daily email quotas apply and can change.
- Privacy rules vary. Ask your attorney.
- We sell build work. Read this with that in mind.
- No ReRev prices and no promises about results.
If you want help with this, or want to claim a free rebuild of a tool you pay for, tell us what you use. Do not send passwords or login details.
Frequently asked questions
Why is my Lovable contact form not sending email?
A web page cannot send email by itself. Something has to receive the submission. Check where your form posts to.
Can I get form emails for free?
One option is a Google Apps Script web app, as in this post. It uses your own Google account and its daily email limits.
How do I stop spam from the form?
A hidden field catches simple bots. It will not stop everything. The script also caps message length and pauses when your quota runs low.
Does the script store submissions?
No. It only sends an email.
Who should receive the notification?
You decide. Ask the people involved before you copy anyone.
Did you test this in Google?
No. I tested it with a mock in Node. Run the test steps before you rely on it.
Read next: Send Lovable form submissions to Google Sheets if you want submissions stored in a sheet, not just emailed.