You have a form on your website. You want the data in Google Sheets. You don't want to write a backend server. This is one of the most common problems in web development, and there are several ways to solve it.
In this guide, we'll walk through three methods — from the DIY approach with Google Apps Script, to the simplest option with Sheet Monkey, to a brief look at other services. Each method includes working code you can copy and use today.
Method 1: Google Apps Script (Free, But Complex)
Google Apps Script lets you write server-side JavaScript that runs inside Google's infrastructure. You can create a web app that receives form data and writes it to a Google Sheet.
Step 1: Create your Google Sheet
Create a new Google Sheet and add column headers in the first row that match your form field names. For example: Name, Email, Message.
Step 2: Open the Apps Script editor
Go to Extensions > Apps Script in your Google Sheet. This opens the script editor.
Step 3: Add the script
Delete any existing code and paste this:
function doPost(e) { var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]; var row = []; for (var i = 0; i < headers.length; i++) { var header = headers[i]; if (header === 'Timestamp') { row.push(new Date()); } else { row.push(e.parameter[header] || ''); } } sheet.appendRow(row); return ContentService .createTextOutput(JSON.stringify({ result: 'success' })) .setMimeType(ContentService.MimeType.JSON); }
Step 4: Deploy as a web app
- Click Deploy > New deployment.
- Select Web app as the type.
- Set "Execute as" to Me and "Who has access" to Anyone.
- Click Deploy and copy the web app URL.
Step 5: Create your HTML form
<form action="YOUR_APPS_SCRIPT_URL" method="POST" > <input type="text" name="Name" placeholder="Your name" required /> <input type="email" name="Email" placeholder="Your email" required /> <textarea name="Message" placeholder="Your message" required></textarea> <button type="submit">Send</button> </form>
The downsides of Apps Script
This method is free and uses Google's own infrastructure, but it has real problems:
- CORS issues. If you submit the form via JavaScript (fetch or XMLHttpRequest), you'll hit CORS errors. The form must submit as a traditional POST, which means a full page redirect.
- Debugging is painful. Apps Script errors don't show up in your browser console. You have to check the Apps Script execution log, which is often unhelpful.
- Maintenance burden. When Google updates the Apps Script runtime or changes API behavior, your script can break without warning.
- No features. No file uploads, no email notifications, no autoresponders, no custom redirects. Just raw data into a sheet.
- Rate limits. Google imposes quotas on Apps Script executions that can silently drop submissions during traffic spikes.
Pros:
- Completely free
- No third-party service required
- Runs on Google's infrastructure
Cons:
- CORS issues with JavaScript submissions
- Painful debugging experience
- Breaks when Google updates APIs
- No file uploads, notifications, or autoresponders
- Rate limits can drop submissions silently
Method 2: Sheet Monkey (Recommended — 60-Second Setup)
Sheet Monkey is a service that gives you a form endpoint URL. Point your HTML form at it, and submissions go directly into your Google Sheet. No backend code, no Apps Script, no middleware.
Step 1: Create a Sheet Monkey account
Sign up for free and connect your Google account. Select the Google Sheet where you want form data to go.
Step 2: Get your form endpoint
Sheet Monkey gives you a unique URL for your form. It looks like:
https://api.sheetmonkey.io/form/your-unique-id
Step 3: Build your HTML form
<form action="https://api.sheetmonkey.io/form/your-unique-id" method="POST" > <input type="text" name="Name" placeholder="Your name" required /> <input type="email" name="Email" placeholder="Your email" required /> <textarea name="Message" placeholder="Your message" required></textarea> <button type="submit">Send</button> </form>
That's it. When someone submits this form, the data appears in your Google Sheet immediately.
What you get for free
Sheet Monkey's endpoint isn't just a data pipe. Even on the free tier, you get:
- Automatic timestamps on every submission
- File uploads — add
<input type="file">and files are stored and linked in your sheet - Email notifications — get notified when someone submits your form
- Autoresponder emails — send automatic confirmation emails to submitters
- Custom redirects — send users to a thank-you page after submission
- Write-only security — your endpoint can only add rows, never read your sheet data
JavaScript (AJAX) submission
If you want to submit without a page redirect, Sheet Monkey works with fetch:
const form = document.querySelector('form'); form.addEventListener('submit', async (e) => { e.preventDefault(); const data = new FormData(form); const response = await fetch(form.action, { method: 'POST', body: data, }); if (response.ok) { alert('Form submitted successfully!'); form.reset(); } });
No CORS issues. No Apps Script debugging. It just works.
Pros:
- Setup in under a minute
- No backend code to write or maintain
- File uploads, notifications, autoresponders built in
- Works with any HTML form on any platform
- Write-only security model
- AJAX submissions work without CORS issues
Cons:
- Free tier limited to 100 submissions/month
- Paid plans start at $5/month for unlimited (see pricing)
Method 3: Other Services (Brief Comparison)
There are other services that can accept form data, but most don't send it directly to Google Sheets:
Formspree
Formspree is a form backend that sends submissions to your email. It doesn't have native Google Sheets integration — you'd need Zapier ($20+/month) to bridge the gap. Free tier: 50 submissions/month. See our detailed comparison.
Zapier + Google Forms
You could use Google Forms for data collection and connect it to a sheet via Zapier. But Google Forms can't be styled to match your site, and Zapier adds cost and latency. This is overkill for most use cases.
SheetDB / Sheet.best
These services turn your Google Sheet into a full REST API (read and write). They're designed for apps that need to read data back from the sheet, not just collect form submissions. If you only need to send form data to a sheet, they're overkill — and the read access means your sheet data is exposed via the API.
Comparison Table
| Feature | Apps Script | Sheet Monkey | Formspree + Zapier | SheetDB |
|---|---|---|---|---|
| Price | Free | Free (100/mo) | $20+/month | $7/month |
| Setup | 30+ minutes | Under 1 minute | 15 minutes | 10 minutes |
| Google Sheets native | Yes | Yes | No (requires Zapier) | Yes |
| File uploads | No | Yes | Paid only | No |
| Autoresponder | No | Yes | No | No |
| Custom redirects | No | Yes | Yes | No |
| AJAX support | CORS issues | Works | Works | Works |
| Maintenance | You maintain it | Managed | Managed | Managed |
Advanced: Adding Features to Your Form
Once your basic form is working with Sheet Monkey, you can add features without any backend changes.
File uploads
Add a file input to your form. Sheet Monkey stores the file and adds a link in your Google Sheet:
<input type="file" name="Resume" />
Custom redirects
Redirect users to a thank-you page after submission by adding a hidden field:
<input type="hidden" name="_redirect" value="https://yoursite.com/thank-you" />
Hidden timestamp fields
While Sheet Monkey adds timestamps automatically, you can also capture the user's local timestamp:
<input type="hidden" name="Submitted_At" id="timestamp" /> <script> document.getElementById('timestamp').value = new Date().toISOString(); </script>
UTM parameter capture
Track which ad campaigns generate form submissions by capturing UTM parameters:
<input type="hidden" name="utm_source" id="utm_source" /> <input type="hidden" name="utm_medium" id="utm_medium" /> <input type="hidden" name="utm_campaign" id="utm_campaign" /> <script> const params = new URLSearchParams(window.location.search); ['utm_source', 'utm_medium', 'utm_campaign'].forEach(param => { const el = document.getElementById(param); if (el) el.value = params.get(param) || ''; }); </script>
Read more about tracking UTM conversions in Google Sheets.
Working with Different Frameworks
Sheet Monkey works with any platform that supports HTML forms:
- React — Use controlled components or form refs
- Vue — Works with v-model and async methods
- JavaScript — Fetch API or XMLHttpRequest
- Webflow — Custom form action in the designer
- Carrd — Form widget with custom action URL
- WordPress — Contact Form 7 or any form plugin
Frequently Asked Questions
Can I use this with any website builder?
Yes. If your website builder supports HTML forms with a custom action attribute, it works with Sheet Monkey. This includes Webflow, Carrd, Squarespace, WordPress, Wix (with custom code), and any static site.
Is my data secure?
Sheet Monkey endpoints are write-only. They can add rows to your Google Sheet but can never read data from it. Your existing spreadsheet data is always protected. See our security documentation for more details.
How many submissions can I send?
Sheet Monkey's free tier includes 100 submissions per month. Unlimited plans start at $5/month. See our pricing page for details.
Can I submit the form without a page redirect?
Yes. Use JavaScript's fetch API to submit the form data via AJAX. Sheet Monkey handles CORS properly, so fetch submissions work from any domain. See the JavaScript example above.
Does this work with Google Workspace (business) accounts?
Yes. Sheet Monkey works with both personal Google accounts and Google Workspace accounts.
Get Started
Try Sheet Monkey free — 100 submissions/month, no backend code, setup in under a minute.