How to submit HTML forms to Google Sheets. (Updated for 2021 Script Editor)

Overview

Submit a HTML form to Google Sheets

How to submit a simple HTML form to a Google Sheet using only HTML and JavaScript. Updated for Google Script Editor 2021 Version.

This example shows how to set up a mailing list form that sends data to Google Sheets but you can use it for any sort of data.

1. Set up a Google Sheet

  1. Go to Google Sheets and create a new sheet. This is where we'll store the form data.
  2. Set the following headers in the first row:
A B C ...
1 Date Email Name

2. Create a Google App Script

Click on Tools -> Script editor. This will open new Google Script. Rename it to something like "Mailing List".

Replace the myFunction() { ... section with the following code snippet:

// Original code from https://github.com/jamiewilson/form-to-google-sheets
// Updated for 2021 and ES6 standards

const sheetName = 'Sheet1'
const scriptProp = PropertiesService.getScriptProperties()

function intialSetup () {
  const activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
  scriptProp.setProperty('key', activeSpreadsheet.getId())
}

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(function(header) {
      return header === 'Date' ? 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()
  }
}

Save the project before moving on to the next step.

3. Run the initialSetup function

You should see a modal asking for permissions. Click Review permissions and continue to the next screen.

Because this script has not been reviewed by Google, it will generate a warning before you can continue. You must click the "Go to Mailing List (Unsafe)" for the script to have the correct permissions to update your form.

After giving the script the correct permissions, you should see the following output in the script editor console:

Now your script has the correct permissions to continue to the next step.

4. Add a trigger for the script

Select the project "Triggers" from the sidebar and then click the Add Trigger button.

In the window that appears, select the following options:

  • Choose which function to run: doPost
  • Choose which deployment should run: Head
  • Select event source: From spreadsheet
  • Select event type: On form submit

Then select "Save".

5. Publish the project

Now your project is ready to publish. Select the Deploy button and New Deployment from the drop-down.

Click the "Select type" icon and select Web app.

In the form that appears, select the following options:

  • Description: Mailing List Form (This can be anything that you want. Just make it descriptive.)
  • Web app → Execute As: Me
  • Web app → Who has access: Anyone

Then click Deploy.

Important: Copy and save the web app URL before moving on to the next step.

6. Configure your HTML form

Create a HTML form like the following, replacing YOUR_WEBAPP_URL with the URL you saved from the previous step.

<form 
  method="POST" 
  action="YOUR_WEBAPP_URL"
>
  <input name="Email" type="email" placeholder="Email" required>
  <input name="Name" type="text" placeholder="Name" required>
  <button type="submit">Send</button>
</form>

Now when you submit this form from any location, the data will be saved in the Google Sheet. 🥳

Note: If you want to intercept the submit event so the user isn't redirected to the webapp, you can do this by attaching a JavaScript event listener to the form submission and creating the POST request yourself.

Issues?

If you want to submit your HTML forms to Google Sheets without using App scripts, try a free service like Sheet Monkey, which allows you to do submit forms to Google Sheets without any backend code.

Thanks

Thanks to the following articles and projects that inspired this guide

Comments
  • Works great but ...

    Works great but ...

    I can get the data to populate the Sheet but when I try to preventDefault and submit using the eventListener I get a CORS error. Any way around this?

    Thanks for the assist!

    opened by vz-dave 5
  • How to redirect after info is logged in form

    How to redirect after info is logged in form

    Its working very well for me but after the form is submitted it just shows {"result":"success","row":1}

    How would i get the page to redirect to another url after the form is submitted

    Sorry if the answer is very obvious, im very new to coding

    Thank you for your work

    duplicate 
    opened by madhavalwadhi 2
  • Google Sheets Updated; Instructions Need Updating

    Google Sheets Updated; Instructions Need Updating

    ** Context Only ** Instructions indicate going to Tools -> Script Editor. Google Sheets has been updated where the "Script Editor" is now "Extensions -> Apps Scripts". Otherwise, the script works as written.

    opened by cphaynes 2
  • Issue regarding saving the File Address when we put

    Issue regarding saving the File Address when we put "File" as Input-Type

    Hey! Thanks for developing such useful code. I am looking forward to your guidance, how we can get the file address once uploaded via HTML File input type.

    Looking forward to hearing from you.

    opened by Ramneek-kalra 2
  • Exposing MY_WEBAPP_URL on the Frontend

    Exposing MY_WEBAPP_URL on the Frontend

    Is it safe to let the MY_WEBAPP_URL be exposed on the Frontend? Because any malicious user can use this URL and post a bulk amount of garbage data into my spreadsheet.

    Is there any way to prevent this without building my own API endpoint?

    Thank you.

    opened by Kingkon963 1
  • How do I use the provided code to interrupt and have the form redirect once submitted?

    How do I use the provided code to interrupt and have the form redirect once submitted?

    The code for this is working for me and my form submissions are going into the google sheet however I cannot figure out how to use the provided code to interrupt and have the form redirect once submitted.

    opened by Afogle317 1
  • Run very well but i have a issue with input checkbox

    Run very well but i have a issue with input checkbox

    Describe the bug

    Hi man, First i congrats, its a good job My issue being with input checkbox, the app return me value for all input but don't checkboxes checked. Can you help me please?

    To Reproduce Steps to reproduce the behavior: My HTML :

    `

        DIGITE SEU ENDEREÇO <input type="text" required="" name="endereço" placeholder="rua,nº,bairro cidade"><br>
    COPIE E COLE O ENDEREÇO DO MAPA <input type="url" name="end" placeholder="Localização (opcional)"><br><br>
    
    
    <label>HATCH <input type="checkbox" name="ch[]" value="60" /></label>
    <label>SEDAN <input type="checkbox" name="ch[]" value="60" /></label>
    <label>CROSSOVER <input type="checkbox" name="ch[]" value="60" /></label>
    <label>SUV <input type="checkbox" name="ch[]" value="60" /></label>
    <label>MINIVAN <input type="checkbox" name="ch[]" value="70" /></label>
    <label>PICUP <input type="checkbox" name="ch[]" value="70" /></label>
    <label>STATION WAGON <input type="checkbox" name="ch[]" value="70" /></label>
    <label>CONVERSÍVE <input type="checkbox" name="ch[]" value="70" /></label>
    <label>CUPE <input type="checkbox" name="ch[]" value="70" /></label>
    <label>LUXO <input type="checkbox" name="ch[]" value="70" /></label><br><br>
    

    ADICIONAIS


    <label>LAVAGEM (SECO) DE MOTOR <input type="checkbox" name="ch[]" value="20" /></label>
    <label>CERA PLUS <input type="checkbox" name="ch[]" value="20" /></label>
    <label>CHEIRINHO <input type="checkbox" name="ch[]" value="10" /></label>
    
    
    <label>VALOR <input type="text" name="result" id="result" value="R$ 0,00" /></label><br>
    
    <button type="submit" value="ENVIAR">
    

    `

    Expected behavior

    I just copy and past your code no change. I need just checked boxs to appear in my sheets.

    Screenshots image

    image

    Desktop

    • OS: [e.g. iOS]
    • Browser [e.g. chrome, safari]
    • Version [e.g. 22]

    Additional context

    The input name="result" dont appear in sheet too.

    Thanks again.

    opened by thiagoflaminio 1
  • PREVENT FORM LOADING

    PREVENT FORM LOADING

    The function below prevents my form from loading once I hit the submit button however, the text in my input are not submitted to my google sheet.

    Once I comment this function out, the form is submitted but it loads to my webapp. How do I resolve this?

    window.addEventListener("load", function() { const form = document.getElementById('bay-form'); form.addEventListener("submit", function(e) { e.preventDefault(); const data = new FormData(form); const action = e.target.action; fetch(action, { method: 'POST', body: data, }) .then(() => { alert("Success!"); }) }); });

    opened by cliffordaddison 0
  • Excel Function Injection

    Excel Function Injection

    Describe the bug It is possible to inject functions in the response. This may lead to additional vulnerabilities.

    To Reproduce Steps to reproduce the behavior:

    1. Setup the script as described in the Readme (using a name column)
    2. Run: curl "https://script.google.com/macros/s/AKfy..._5tS/exec" -X POST -d 'name==SUM(a1:a2)'

    Expected behavior It should not be possible to inject functions.

    Screenshots This vulnerability will inject the supplied function as proper sheets function: image

    Possible solution: For now, I have mitigated this by stripping any leading = symbol from each submitted input:

        const newRow = headers.map(function(header) {
          return header === 'Date' ? new Date() : (e.parameter[header] || "").replace(/^=+/,'')
        })
    

    Not sure though if there may be additional attack vectors using a similar approach.

    opened by FaKeller 0
  • How to add dropdown list auto update in google sheet userfrom html

    How to add dropdown list auto update in google sheet userfrom html

    I was searching on the internet for an auto refresh drop down list to add in a form html your.

    https://youtu.be/pmQdrAIdfGM I found this video, but it didn't work. If you have a way, my friend, share it with me

    opened by mohamedabofayz 0
  • In reference to the google app script security

    In reference to the google app script security

    Excellent work! It worked perfectly for me, I was able to put a form on my test page and everything works fine. I just had a big doubt, is it safe to post the URL to my google script on the client side? Is there any way that someone with bad intentions can do something wrong? I understand that the script only allows to edit the spreadsheet that I gave it access to, and nothing more than that, is that correct? Or does the script give extra permissions that I'm not seeing? And my last question, I wanted to know if anyone knows how I can use Kor Connect to hide the URL of the script, because I understand that it is handled as an API, or is it not? Here I leave the query I made in the Kor forum, in case someone knows what I can do. Thanks! https://discourse.korconnect.io/t/hide-google-script-web-app/605

    opened by ibrunops 0
  • Form redirect request

    Form redirect request

    This is a fantastic overview, and it works great. The only issue I have is finding a way to redirect the page to another URL after submission.

    It returns a success page, however it does not redirect.

    image

    What code would I need to add inside of this Javascript to redirect the user, instead of them seeing the message above?

    Thanks!

    opened by siferiandude12 6
  • Unable to use textarea

    Unable to use textarea

    Hi there, First of all I wanna thank you for this project, it's very usefull.

    Though I have a little issue, I'm unable to get data from textarea in a sheet. So for example, this doesnt't work.

    <div class="styled-input wide">
      <label style="padding: 0; position: relative;">Opmerkingen</label>
      <textarea name="Opmerkingen" id="Opmerkingen" style="resize: vertical;"></textarea>
    </div>
    

    Though this does:

    <div class="styled-input wide">
      <label style="padding: 0; position: relative;">Opmerkingen</label>
      <input type="text" name="Opmerkingen" id="Opmerkingen" style="resize: vertical;"></input>
    </div>
    

    Am I doing things wrong or is there something I can change in the Gscript to get it working?

    Thanks!

    opened by MiroVerleysen 0
Owner
Levi Nunnink
IndieHacker⚡️ Coffee is on me
Levi Nunnink
CoWIN Vaccination Tracker, Below is the PRODUCTION LINK this is updated at end of each day. To see any latest Updates, please check the documentation

CoWIN Vaccination Slots Checking App. CoWIN Vaccination Slots Checking App is a user-friendly website that allow users to find vaccine in nearby avail

Stephin Reji 31 Jan 28, 2022
A node script that lists the cities on Santa's route from santatracker.google.com

Google Santa Route A script that lists the cities on Santa's route from santatracker.google.com based on the JSON containing all Santa's destinations.

Emile Calixte 1 Dec 24, 2021
Build forms in React, without the tears 😭

Build forms in React, without the tears. Visit https://formik.org to get started with Formik. Organizations and projects using Formik List of organiza

Formium 31.7k Jan 5, 2023
📋 React Hooks for forms validation (Web + React Native)

English | 繁中 | 简中 | 日本語 | 한국어 | Français | Italiano | Português | Español | Русский | Deutsch | Türkçe Features Built with performance and DX in mind

React Hook Form 32.4k Dec 29, 2022
An open source application to create, manage and embed contact forms on static/dynamic sites with no code

Formify is an open source application that lets you create, manage and embed contact forms on any site without writing code. This project is done as a

Basharath 37 Dec 26, 2022
An intro to Three.js and React :) Workshop materials and demo from HackTheNorth 2021

?? Speedy 3D - A Quick Intro to Three.js & React This workshop was originally created for Hack The North 2021! My personal motivation was to: learn th

Anson Yu 8 Dec 17, 2021
During work. Second team project created during CodersCamp 2021/2022 by a 6-person team.

BoardMap Status: Work in progress. Work on the project started on 10-01-2021. Our Crew Mentor: Piotr Rynio Agnieszka Przybyłowska Patryk Święcicki Rad

Piotr Rynio 3 Mar 21, 2022
An implementation of React v15.x that optimizes for small script size

react-lite Introduction react-lite is an implementation of React that optimizes for small script size. Note: react-lite dose not support React v16.x n

工业聚 1.7k Dec 10, 2022
A very lightweight and flexible accessible modal dialog script.

A11y Dialog This is a lightweight (1.3Kb) yet flexible script to create accessible dialog windows. Documentation ↗ Demo on CodeSandbox ↗ Features: Clo

Kitty Giraudel 2.1k Jan 2, 2023
Script to remove unnecessary properties from package.json on prepublish hook

clean-pkg-json Script to remove unnecessary properties from package.json on prepublish hook. Support this project by ⭐️ starring and sharing it. Follo

hiroki osame 37 Oct 16, 2022
Next-gen, highly customizable content editor for the browser - based on React and Redux and written in TypeScript. WYSIWYG on steroids.

ReactPage ReactPage is a smart, extensible and modern editor ("WYSIWYG") for the web written in React. If you are fed up with the limitations of conte

null 9.1k Jan 6, 2023
Tina is an open source editor that brings visual editing into React websites. Tina empowers developers to give their teams a contextual and intuitive editing experience without sacrificing code quality.

Tina is an open-source toolkit for building content management directly into your website. Community Forum Getting Started Checkout the tutorial to ge

Tina 8.2k Jan 1, 2023
A text editor built with react , firebase and quill

Welcome to Text-Editor ?? A simple text editor built with react,firebase v8 & quill ✨ Demo Install npm install Usage npm run start Run tests npm run t

Whirl 4 Aug 30, 2022
Visual layout editor for matplotlib and any plotting library built upon matplotlib like seaborn.

Matplotlib Layout Generator Before you start: You must have experience with using matplotlib. It needs to be use on desktop. Not designed for mobile.

null 4 Dec 1, 2022
💻 Build your own code editor that compiles and runs 40+ programming languages.

CodeRush - Compile and Execute code in 40+ languages ⚡️ A code editor that compiles and runs your code on the web. Blog: FreeCodeCamp - Build A Code I

Manu Arora 133 Jan 1, 2023
A set of React components implementing Google's Material Design specification with the power of CSS Modules

React Toolbox is a set of React components that implement Google's Material Design specification. It's powered by CSS Modules and harmoniously integra

React Toolbox 8.7k Dec 30, 2022
A Google Clone which built with ReactJS. You can click the demo and search whatever you want!

Google Clone with ReactJS A small web app that imitate the desktop web version of google site, you can search whatever you want. Google Clone Demo Lin

Özge Coşkun Gürsucu 36 Aug 14, 2022
React Google Analytics 4

React Google Analytics 4 Migrate from old react-ga // Simply replace `react-ga` with `react-ga4` import ReactGA from "react-ga"; import ReactGA from "

PriceRunner 270 Dec 29, 2022
A Facebook Clone which built with reactJS. You can sign in with your Google Account and send realtime posts.

Facebook Clone with ReactJS A Facebook Clone application that you can sign in with your Google Account and send realtime posts. Facebook Clone Demo Li

Mert Çankaya 23 Nov 25, 2022