This project shows how to create a simple, secure HTML contact form that submits data directly to a Google Sheet using Google Apps Script – no backend required.
- Save contact form submissions to Google Sheets
- Uses only HTML, JavaScript, and Google Apps Script
- Works without a backend server
- Includes automatic timestamp (date) logging
- Supports CORS-friendly
FormData
POST submission
- Go to Google Sheets.
- Create a new spreadsheet.
- Rename the first tab to:
Sheet1
(or anything you like). - In row 1, enter the following headers:
Name | Email | Message | Date
- Click Extensions → Apps Script in your Google Sheet.
- Replace the default code with this:
const sheetName = 'Sheet1'; // 🔁 Replace 'Sheet1' with your actual sheet name if different
const scriptProp = PropertiesService.getScriptProperties();
function intialSetup() {
const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
scriptProp.setProperty('key', activeSpreadsheet.getId());
}
function formatDate(date) {
return Utilities.formatDate(date, Session.getScriptTimeZone(), 'dd-MM-yyyy HH:mm');
}
function doPost(e) {
const lock = LockService.getScriptLock();
lock.tryLock(10000);
try {
const doc = SpreadsheetApp.openById(scriptProp.getProperty('key'));
const sheet = doc.getSheetByName(sheetName);
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const nextRow = sheet.getLastRow() + 1;
const newRow = headers.map(header => {
return header === 'Date' ? formatDate(new Date()) : e.parameter[header];
});
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]);
return ContentService
.createTextOutput(JSON.stringify({ result: 'success', row: nextRow }))
.setMimeType(ContentService.MimeType.JSON);
} catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ result: 'error', error: e }))
.setMimeType(ContentService.MimeType.JSON);
} finally {
lock.releaseLock();
}
}
3.Save the script.
4.Select intialSetup in the dropdown and click
5.Click Deploy → New Deployment:
-
click settings
-
Select Web App
-
Set Execute as: Me
-
Set Who has access: Anyone (or Anyone with link)
-
Deploy and copy the web app URL.
-
⚠️ Important: The name attributes of the form fields must exactly match the header names in your Google Sheet (e.g., Name, Email, Message). -
⚠️ The form id must match what is referenced in your JavaScript (contactForm).
const scriptURL = 'YOUR_DEPLOYED_WEB_APP_URL'; // ← Paste your web app URL here
-
If submissions aren’t appearing:
-
Check if the Sheet tab name matches sheetName
-
Make sure headers (Name, Email, Message, Date) are spelled exactly
-
Check Apps Script → Executions for logs or errors
-
Spreadsheet must be shared with Anyone with the link or set the Web App to “Anyone”
-
-
Google Apps Script deployed as a web app is public (unless secured).
-
Do not use this to collect sensitive data like passwords or private info.
If this project helped you or saved you time, please consider giving it a ⭐️ on GitHub!
Your support encourages me to improve and maintain this project.
If you face any issues, feel free to open an issue — I'm happy to help!