Connect Elementor Form to Google Sheets for FREE without Zapier

Connect Elementor Form to Google Sheets marketing automation

This article will show you how to connect Elementor Form to Google Sheets, linking your Elementor Form widget and Google Sheets in just 10 minutes. I’ll also walk you through the steps while requiring only minimal coding abilities! Zapier is not needed for this task!

This post started after we created a Webinar signup page, with a question registrants could ask upon signing up. However, we wanted to collect all the questions from the submitted forms in a specific Google Sheet document to follow later follow all the questions. By the way, if you’re creating Webinar landing pages makes sure to improve conversion with AI 🙂 

Initially, I believed it would be a short and easy task that would take me 5 minutes. Only later did I discover how tricky this was… But I’ve got you all covered in this post.

Elementor Form to Google Sheets in No Time

If you want to go the straightforward path, you can connect Elementor Form to Zapier. Respectively, it will cost you $20 per month. In this article, I will show how we did it for free and saved hundreds of dollars!

How to Connect Elementor Form To Google Sheets?

Google Sheets allows us to add code to our sheets and deploy this code as a webhook even better. This means our code gets a unique URL that can be triggered externally by our Elementor Form post submit action. The webhook allows us to create the required connection between Elementor Form to Google Sheets, and we're done! The following steps will describe everything you need to know.

Woman looking at Elementor Forms that connect with Google Sheets
Total Time Needed: 15 minutes
Total Cost: 0 USD

Required Tools:

- Elementor Form Widget.
- Google Sheets.
- Basic Coding Skills.

Things Needed?

- A WordPress Website.
- Elementor Plugin.
- Google Sheets Document.

Steps to connect Elementor Form to Google Sheets

Step 1: Create a new Google Sheet document
Include the table headers you wish to have in the document. Otherwise, your message from the Elementor Form will not reach correctly in your Google Sheet.
Create new Google Sheet document to connect with Elementor Forms
Step 2: Open Scripts Editor for Google Sheets in the Top bar
Here we're going to write the code for our webhook and integrate it with our document to connect our Elementor Form to Google Sheets.
Open Script Editor in Google Sheets
Override the default myFunction() with the code you can find here, and then copy everything and replace it.
Paste code into Google Sheets Editor
Step 4: Save the Code and Create a new Deployment
Save the code to make sure you don't lose anything. Only after saving will you be able to deploy your code.
Create a new Deployment to connect Elementor Forms to Google Sheets
Step 5: Choose Deployment Type as Web App
Give your Web App a convenient name that you can recognize.
Create Web App Deployment
Step 6: Set Execution permission and Allow Access
Execute the Web App from your user and give Anyone access. This would make your webhook public. It is important to remember - this URL is available to everyone.
Deploy the Google Sheets Web App
Step 7: Authorize Access to the Web App
Once you choose a Web App - click deploy again. You will now be prompted to Authorize access and let the script operate on your behalf. Important to make this work. Otherwise, the script can't access your Google Sheet.
Approve Google Sheets Script Editor
Step 8: Run the initialSetup function
Important Step! Run this only once before starting. This tells the script to work on the given Google Sheet. Choose the initialSetup on the top menu and click Run.
run the inital method in Script editor
Step 9: Define a Trigger in Google Sheets Script Editor
On the left menu, click the "Clock" icon that says triggers. We need to tell the script when to operate. Click Add Trigger on the lower right corner of the screen.
Set a trigger to connect Elementor Forms to Google Sheets
Step 10: Choose Function to run and Event Type
We need to change two fields: Choose Function to run: doPost Choose Event Type: On form submit Once chosen hit save and continue the process 🙂 
Give you Script running permissions in Google Sheets
Step 11: Copy your Web App URL to Elementor
This URL is your Webhook URL - the one we will set in Elementor and define as our webhook. If you need to test anything - this is the URL you want to use!
Webhook used to connect Elementor Forms to Google Sheets
Step 12: Set field label names
The names we give the field labels are the names of the fields in the Webhook! This means that the data Elementor sends to our code in Google Sheets has the label's names. They must match the code (but not case sensitive, for example, Message and message work). Leave as default (Email, Name, Message) to work with the example code.
Set the fields in the webhook between Elementor Forms to Google Sheets
Step 13: Define Actions After Submit with Webhook
Choose this option from the dropdown in the Actions After Submit dropdown menu.
Choose webhook in the elementor form options
Step 14: Paste the Webapp URL we copied in the Elementor Form
Now it's time to take the URL we received previously from our Google Sheets deployment and paste it here. This tells the Elementor form to send data to this address once a form is submitted and connects Elementor and Google Sheets. Don't tick "Advanced Data" - It is not necessary for this stage. It just sends an extra field in the webhook, which we don't currently need.
Paste the Webhook URL we copied
Step 15: Create a new Elementor Form
Choose the Elementor Form from the Elementor Widgets menu.
Create a new form in Elementor
Step 16: Save the Elementor Form and try to submit data!
Update the file and open it in preview. Important - Form submission does not work while editing. You must go to preview mode to test it.
Input text to check the Elementor Forms to Google Sheets integration
Step 17: The Final Result - Elementor Form Connected to Google Sheets!
Go back to your Google Sheet and enjoy the results! You should now see your entry from the submitted form here. We successfully managed to connect Elementor Form to Google Sheets!
It works! You connected Elementor Forms to Google Sheets

[Code Stuff] Field Validation

I wanted to make sure that only Form submissions with Message fields are saved in Google Sheets.

For that, I added in the code this line:

const mandatoryFields = [‘message’]

Make sure to either keep, delete the value (make it []) or update the fields in this array. This defines which areas must have values before saving data in Google Sheets.

Connect Elementor Form to Google Sheets with this code 🎉

This code is a mix of parts found over the internet with the authors’ credits, who helped me at the bottom. Special Credits to Jamie Wilson and Omer Lahav.

// In case you want to change the Sheet name
var sheetName = 'Sheet1'
var scriptProp = PropertiesService.getScriptProperties()

// Lowercasing all input keys in the POST data by default (to avoid Message vs message confusion)
var shouldLowerCaseHeaders = true

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

function filterRow (parameters, mandatoryFields) {
    return mandatoryFields.every(field => parameters[field.toString().toLowerCase()] && parameters[field.toString().toLowerCase()].length > 0)

function doPost (e) {
  var lock = LockService.getScriptLock()
  // Uncomment and add fields which must be mandatory when submitting a form
  //const mandatoryFields = ['questions']
  const mandatoryFields = []

  try {
    // Get the current open Google Sheet
    var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    var sheet = doc.getSheetByName(sheetName)

    // IMPORTANT: Create headers in your google sheet first
    //            If you dont create headers this won't match the data
    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    var nextRow = sheet.getLastRow() + 1

    var parameters = e.parameter;

    // Lower casing header keys - True by default
    if (shouldLowerCaseHeaders){
      Object.entries(e.parameter).map(([key, value]) => parameters[key.toString().toLocaleLowerCase()] = value)
    const shouldInsertToSheet = filterRow(parameters, mandatoryFields)
    if (shouldInsertToSheet){
      var newRow = {
        return header.toString().toLowerCase() === 'timestamp' ? new Date() : parameters[header.toString().toLowerCase()]
      sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])
    return HtmlService.createHtmlOutput("post request received");

  catch (e) {
      return HtmlService.createHtmlOutput("post request received");

  finally {

If you’re looking for more great tips about Elementor, make sure to check out the full Elementor Tips list on the site!

Join My Journey Into The New Economy

Stay up to date on Web3, NFTs and Crypto,
curated just for you.

Guy Eshet

Guy Eshet

Guy Eshet is an expert in Blockchain technologies, NFTs, and Web development. Guy has been developing software for over 15 years, currently focusing on Web3. Guy is fluent in 5 languages, loves meeting new people, learning about various topics, and improving his skills.

Share this article!

36 Responses

  1. if i am already follow your tips, and after submit show this message
    “Webhook Webhook Error
    This Message is not visible for site visitors.”

    how i can fix this?

    1. Hey Fadel,
      Webhook error can be caused by many types of errors, but what I would check is that you copied the URL of the Google we hook correctly.
      Additionally you can take a look at the error dashboard in the Google code editor to see if and error were logged there

      Good luck!

  2. Hi, my page has also started getting errors (“Webhook Error”). Your code worked fine for weeks now it ends-up with the error not every time but most of the times I try to submit the form. What’s interesting the code itself is executed entirely and the responses are recorded as expected.

    Webhook error means the receiving server responded with response code other the 200. So maybe Google has changed something in the appscript IDE or they simply have a bug. Anyways the script currently doen’t work reliably (which is not the author’s fault).

    Unfortunately I cannot see the log of execution because the new script IDE doesn’t show the logs for remote webapp execution (I can see the code was run, but the log itself is empty even if I logged anything to the console). Plenty of devs complainted about the way appscript deals with remote post requests and doesn’t log properly.

    1. Hey Rafal
      Thanks a lot for the elaborate response! So sad to hear it’a not working…
      I’m actually traveling abroad right now, but once I return I’ll try to figure out a hack around it 🙂

      1. I changed HtmlService.createHtmlOutput(“post request received”) to just HtmlService.createHtmlOutput() and it seems to fix the issue (at least for me).

        1. Hey Rafal!
          I got back home and tested things again, seems like it’s working.
          I changed the default mandatory fields array to be an empty array. This way it will not require any field validation upon submission.
          Thanks for the elaborate test!

    1. Hey there,
      I tested things again with my code and everything seems to run, maybe you somehow didn’t copy the URL correctly?
      One thing to notice which I’ve also highlighted in the code,
      Looks for

      // Uncomment and add fields which must be mandatory when submitting a form
      //const mandatoryFields = ['questions']
      const mandatoryFields = []

      and make sure this is empty, otherwise this will require you submitting a ‘questions’ field as well.
      The default was ‘questions’, which I now changed to an empty array.

      I hope this helps!

    1. Hey Novan!
      I’m not sure I understand your questions. Did you mean what happens if you change the name of the sheet?

      In that case, change this at the beginning of the code:
      var sheetName = ‘Sheet1’

      to reflect the name of the sheet where you would like your data to be saved.
      Let me know if this helps!

  3. Hi Guy! It’s Rafal again.
    Could you let me know why there’s a need to add the trigger for onFormSubmit?
    I’ve just deployed the code as a web app WITHOUT adding the oFS trigger and it works just fine. Is there any particular reason the oFS has to be added?

    Thanks for any response.

  4. Guy, Great Job and Thanks for sharing. I added Elementor Form Actions After Submit Email to Webhook and once submit is pressed form responds with red “X error” below form. How do we extend this to send email notifications. Can Elementor send email After submit ? or do we need to install google apps script “email notifications for google forms”

    1. Hey there,
      I believe that Elementor can send you an email as described.
      Did you mean sending a mail to an admin for every submitted form for example?
      Or did you mean to send an email to the person who filled out the form?

      The first use case should work just fine…
      In the second case – you might have to use a plugin or a mailing list webhook.

      Another thing, if you disable the Webhook action, does the email work fine?

      Good luck!

  5. That’s just simply brilliant!

    I struggled to set it up for like 30 minutes, but now it works! And 30 minutes is nothing for the thing you did!

    For less experienced I guess video would be great, but well most will manage without it anyway.

    Kudos man!

  6. Hi Guy,
    really appreciate your work man.
    thank you very much.

    just had a query is there an option to get the submission source also in the google sheet, i want to know from where the form has been submitted.

    1. Hey Faheem,
      I’m happy this guide helped you!
      Yes, you can definitely add the submission source.
      Add a hidden field in your form, and give it a fixed value of the page title (Elementor lets you do it).
      Add the name of this hidden field as one of your columns in the Sheet and it should work out of the box.

      Good luck!

  7. Hey Guy! Great blog and it works great!!!

    Would it be possible to help me add something to the script?

    I would like to take the page URL that the Elementor form is found on and pull that into the sheet next to timestamp.

    1. Nevermind I figured it out.

      For anyone interested you use the hidden value as Guy suggested in a previous reply, and set the default value to (click dynamic tags) “request parameter”

      example page with a form on:

      Then make the parameter name “utm_source” (what ever is after the ?)

      Make sure you add a new column in your sheet and then it will pull the tracking data.
      In this case the new column would be called “source” and would pull the data “homepage” to the sheet in this instance.

      Thanks and maybe Guy can assist if this is not clear.

      1. Hey Chris!
        Happy this helped!
        Your solution is great, however, another alternative is setting a hidden field as you said, but giving it a dynamic value of the Page Title (Elementor gives you this natively)

        Good luck!


  8. Hello, the code is not working for me. I see the execution environment and I don’t have any errors but the google sheets stays empty.

  9. This is super helpful, thank you!

    I’m wondering if there’s a way to change the header names as well as add one? Instead of name/email/message, I want it to be name/email/instagram/referral.

    Thanks in advance!

    1. Hey Alyssa
      Yeah sure, you need to make sure that the column names on your google sheet, as well as your elementor form, are matching to what you want.
      You can edit the default field names in the form editor to change it

      Good luck!


  10. Hey, I’m already following your tips, and after submitting show this message
    “Webhook Webhook Error
    This Message is not visible for site visitors.”
    I see that all is good with the code and the webhook link also
    could you tell me how I can fix this?
    thank you

    1. Hey Ayoub,
      Not sure about it to be honest… try to make sure that you gave permissions to everything and test it locally.
      Worst case, try starting from scratch again

    1. Happy to help!
      Do you want a couple of forms of the same field structure?

      Then simply create multiple forms, add a hidden field that tells you the name of the form, so you can distinguish them, and follow exactly the same steps.
      You’d get the sheet with the data and the information separated into the submitting form

      If the forms have a different structure, I would use several sheets, not the same one


      1. thank.
        They all have separate structures so several sheets would be the solution though I thought to combine it all under one. guess its possible with a plugin but not this way. thanks

  11. If you (like me) get a webhook error whilst using Guy’s code, that means your version of Elementor together with WP installation and server settings won’t work reliably. Period.

    To work around this you need to modify functions php (visit: and paste the following code:

    add_action( ‘elementor_pro/forms/new_record’, function( $record, $handler ) {
    //make sure its our form
    $form_name = $record->get_form_settings( ‘form_name’ );

    // Replace MY_FORM_NAME with the name you gave your form!
    if ( ‘FORM15032022’ !== $form_name ) { return; }

    $raw_fields = $record->get( ‘fields’ );
    $fields = [];
    foreach ( $raw_fields as $id => $field ) { $fields[ $id ] = $field[‘value’]; }

    // Replace http://YOUR_WEBHOOK_URL with the actual URL you want to post the form to for example:

    wp_remote_post( ‘HTTP://YOUR_WEBHOOK_URL’, [ ‘body’ => $fields, ]);
    }, 10, 2 );

    This works. Every. Single. Time.
    The downside is that you need to modify this code to work with every new form you create and want to trigger a webhook


      1. Hey Aaron,
        I took a look at the video you sent and two things I saw:

        1. Try without pasting the additional code at functions.php, does this work?
        2. You forget to replace the FORM_NAME at the code you pasted:

        // Replace MY_FORM_NAME with the name you gave your form!
        if ( ‘FORM15032022’ !== $form_name ) { return; }

        This is not your form name, you’d find yours at the top of the Elementor form widget. You need to replace it in order for the code to work,

        But anyhow, I’d try without this code first to check if things work or not

        Good luck!

Leave a Reply

Your email address will not be published.