How to send landing page leads to Google Sheets
You don't need Zapier or a paid plugin. A short Google Apps Script turns a Sheet into a free endpoint that your landing page form can post to.
Updated 24 October 2026 · By Monish Kumar, founder of SprintWebs
What you'll set up
- A Google Sheet with one column per form field
- A small Apps Script that adds a row for each submission
- The script deployed as a web app (a URL your form posts to)
- A few lines of JavaScript on your page
It takes about 15 minutes and costs nothing.
Step 1: Create the sheet
Create a Google Sheet, rename the first tab to Leads, and type your column names in row 1. Use the same names as your form's name attributes, plus a timestamp, for example:
timestamp | name | phone | city | utm_source | utm_campaign
Step 2: Add the script
In the sheet, open Extensions → Apps Script, delete the sample code and paste:
const SHEET_NAME = 'Leads';
function doPost(e) {
const lock = LockService.getScriptLock();
lock.waitLock(10000); // one write at a time
try {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const data = e.parameter; // fields sent by the form
const row = headers.map((h) => (h === 'timestamp' ? new Date() : safe(data[h] || '')));
sheet.appendRow(row);
return ContentService.createTextOutput(JSON.stringify({ ok: true }))
.setMimeType(ContentService.MimeType.JSON);
} finally {
lock.releaseLock();
}
}
// Text starting with = + - @ would run as a formula in Sheets: store it as plain text.
function safe(value) {
const v = String(value).slice(0, 1000);
return /^[=+\-@]/.test(v) ? "'" + v : v;
}
The safe function matters: without it, a visitor could type a formula into your form and it would run inside your sheet.
Step 3: Deploy as a web app
- Click Deploy → New deployment and choose Web app.
- Set Execute as: Me and Who has access: Anyone.
- Click Deploy, approve the permissions, and copy the web app URL (it ends in
/exec).
"Anyone" only lets people submit rows through your script. It doesn't share the sheet itself.
Step 4: Connect your form
Give your form inputs name attributes that match the column names, then add:
<form id="lead">
<input name="name" required placeholder="Full name">
<input name="phone" type="tel" required placeholder="Mobile number">
<input name="city" placeholder="City">
<input name="website" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px" aria-hidden="true">
<button type="submit">Send</button>
</form>
<script>
const ENDPOINT = 'https://script.google.com/macros/s/YOUR_ID/exec';
const form = document.getElementById('lead');
form.addEventListener('submit', async (event) => {
event.preventDefault();
if (form.website.value) return; // bots fill the hidden field
const data = new FormData(form);
const params = new URLSearchParams(location.search);
for (const key of ['utm_source', 'utm_campaign']) data.append(key, params.get(key) || '');
form.querySelector('button').disabled = true;
try {
await fetch(ENDPOINT, { method: 'POST', body: data });
location.href = '/thank-you';
} catch {
alert('Network error. Please try again.');
form.querySelector('button').disabled = false;
}
});
</script>
The hidden website field is a honeypot: real visitors never see it, but spam bots fill it in.
Step 5: Test it
Submit the form from your phone and from a desktop, with and without UTM parameters in the URL (for example ?utm_source=facebook&utm_campaign=test). Check that each row appears within a few seconds with the right columns.
Common problems
- Nothing arrives: you edited the script after deploying. Each change needs Deploy → Manage deployments → Edit → New version.
- Columns are empty: the form's
nameattributes don't exactly match the row 1 headers. - Phone numbers lose the leading +: format that column as plain text (Format → Number → Plain text).
Frequently asked questions
Is it free to connect a form to Google Sheets?
Yes. Google Apps Script web apps are free within Google's daily quotas, which are far above what a typical landing page receives.
Is it safe to set the web app access to Anyone?
It allows anyone to submit data through your script, not to read the sheet. Add a honeypot field, limit field lengths, and neutralise formula characters, as in the code above.
Can I get an email when a new lead arrives?
Yes. Add MailApp.sendEmail('[email protected]', 'New lead', JSON.stringify(e.parameter)) inside doPost, or use Google Sheets' built-in notification rules.