How To Track Form Abandonment in Google Analytics


UPDATE: There is a new version of this form tracking script! Get it here: Form Tracking in Google Tag Manager


A question I hear frequently is “can I track form abandonment in Google Analytics?” The answer is yes, and I’ll explore the details in a moment, but you should first consider alternative solutions.

There are existing solutions (like ClickTale) that do this in a much more elegant manner, with reports dedicated specifically to form analytics. Think of it like the goal funnel visualization reports, but applied to forms.

However, if you don’t want to spend the money on an alternative solution, or you want to keep everything in one place (i.e., Google Analytics), I can help you.

Tracking forms with events

You can use event tracking to find out which fields of your form are being filled out, and which ones are causing people problems. To do this, you can fire an event whenever a user’s cursor exists a field of the form. The easiest way to do this is with a script like below:

Here’s what this script does: when the cursor leaves an input field (if a user tabs to the next field or clicks out of the field) it checks to see if any text was entered. If there is text, it fires an event with a category that you specify (replace the text “INSERT FORM NAME HERE” with the actual name of the form), an action of completed and a label that is set to the name of the form field.

If the field is left blank when the cursor exits, it fires the event with the action set to skipped.

Using the script

Once you’ve downloaded the script, be sure to replace the category (INSERT FORM NAME HERE) with the name of the form you’re tracking. Then, include the script in the <head> section of your html. You’ll also need jQuery, so be sure to include that before the script. You should have something like this:

<script src="//"></script>

<script type=”text/javascript” src=””></script>

What you’ll see

Once you have this script in place and it has collected some data, you’ll start to see the places in your form that users may be having problems.

Go to the Content > Events > Top Events report. Click on the form name (whatever you specified as the event category). That will drill down into the event actions. You’ll see completed and skipped. If you want to see which fields are most commonly skipped, click on that action. To see a more general view of the dropout rate, click on completed.

You’ll see your field names, along with how many total events and unique events occurred for that field.

form tracking in Google Analytics

Unique Events: the number of visits during which one or more events occurred.

You may be wondering why total events and unique events are different. This is because the event is fired every time a user’s cursor exits the field. So if someone fills out their email, then password, then goes back to the email field to change it, then goes on from there, the email field would have 2 total events, but only one unique event.

Things to keep in mind

  • This script requires jQuery. Make sure include the script after you include jQuery, like in the example above.
  • This script pulls in the name attribute of the form field as the event label. Make sure you use descriptive names (as opposed to field1, field2, etc.). Alternatively, if you have descriptive IDs on each form field, you could use those. Just replace $(this).attr(‘name‘) with $(this).attr(‘id‘) in the form tracker script.
  • You may also want to track submissions of the form. You can fire an event when someone clicks the submit button, but that would fire even if the form doesn’t go through (missing fields, invalid input, etc.). Instead, fire the event only after the form has been validated and submitted. This will likely require getting your hands dirty by digging around in the code that executes on form submit.

Jim Gianoglio is a Manager for the Analytics & Insight department. He works with implementation, analysis and training of Google Analytics and Google Tag Manager. Before focusing on analytics, he led the SEO campaigns of Fortune 500 companies in the insurance, retail and CPG industries. Things you didn’t know about Jim: he’s biked from Pittsburgh to Washington DC in 41 hours, roasts coffee beans and has done voiceovers for TV commercials.

  • 1. great idea will implement
    2. wont this do the job for each felled?

  • 1. great idea will implement
    2. wont this do the job for each felled?
    input type=”text” name=”first-name” value=”your first name” onchange=”_gaq.push([‘_trackEvent’, ‘contact’, ‘completed’, ‘first-name’);”

  • Menachem –

    That will do the trick too, with the benefit of not firing the event if someone keeps clicking in and out of a field.

    On the other hand, it won’t show you if someone leaves a field without entering anything.

  • that’s why i used onchange and not onfocus

    thanks for the response

  • Hi Jim, great stuff! I’ve tried to implement your code, but Chrome is reporting the following error in the console:

    Uncaught SyntaxError: Unexpected token )

    Any ideas what might cause that?

  • Martijn –

    I was just looking at the code this morning and noticed the same thing. The cause of the error was a missing } at the end of the else statement. I’ve made the fix and updated the code on GetHub – you can find it here:

    Thanks for the heads up!

  • Hi Jim,

    Could have seen that one myself, thanks for the fix! I’ve modified your code to work within our WordPress installation and calling the code from the functions.php by using the wp_enqueue_script function. Works like a charm now. Now if I only can change the input names Gravity Forms creates to something more understandable…

  • Jim, I just made a small adjustment to your code on GitHub. It now automatically retrieves the form ID from the source, which eliminates the need to manually edit the code to fill in the form name.

  • Thanks Martijn! I’ve been meaning to do that myself 🙂

    I’ve played around with adding tracking to a different form plugin – BWS Contact Form (not used on here, just on one of my personal sites). Unfortunately (or fortunately) the creators of that plugin are quite active and release updates at least once a month. That means anytime I update the plugin, I have to go back in and add the tracking code.

    It makes me want to just create my own plugin, but I don’t have the time or patience at this point to start doing that!

    Thanks for all you comments and adding to the code!

  • Take a look at if you want to track form abandonment. Integrates nicely with Google Analytics and you can try for free.

  • Lenin Rodriguez

    Thanks for your article Jim.
    One question, I’m currently using the basic event tracking on my quote button, but I have the same quote widget in different pages. Is there a way to pull the page where the event was fire?
    This is what I’m using. Thanks in advance.

    onClick=”_gaq.push([‘_trackEvent’, ‘Quote’, ‘Instant’, ‘Submit’,, false]);”

  • Lenin –

    If you go to the Pages report in the Event section of reports (Content > Events > Pages) that will show you which pages events were fired on. You could add a secondary dimension to include the category or action of the event you’re interested in, and then use the inline filter to show just that event (and the associated pages).

    Hope that helps!

  • Great stuff. Thanks, Jim. Implemented this just now.

  • Great work, just what I was after.

    I wanted to make a few changes though that haven’t seemed to work. Basically I only have one field and i want to track the contents of that field when clicking the button rather than the field name itself.

    I’ve got an input field with the id of “url” and an a link with the class of “button”. When I had value=”http://” it was working but returned only the http:// as the value. I swapped that out for placeholder=”http://” but now I’m not getting a value back for the event at all.

    This is the script…. hope you can point me in the right direction.

    (function($) {
    $(document).ready(function() {
    $(‘a.button’).click(function () {
    if($(#url).val().length > 0) {
    _gaq.push([‘_trackEvent’, ‘URL’, ‘completed’, $(#url).attr(‘value’)]);
    else {
    _gaq.push([‘_trackEvent’, ‘URL’, ‘skipped’, $(#url).attr(‘value’)]);

  • Is there any wordpress plugin to add this code for Gravity forms (i’m using it with wordpress) ?

  • @Justin – I like what you’re trying to do. I was going to try to replicate it but got bogged down with other things (client work first!). As soon as I get a chance, I’ll take a look – in the mean time, if you figure it our, please let us know!

    @Roman – I don’t know of any WordPress plugins that add this to Gravity Forms, but if you’re able to include custom JS (depending on your theme) you should be able top implement this regardless of which form plugin you use.

  • @Justin –

    Sorry I didn’t see this sooner. Where you reference the url id, you need to enclose in single quotes.

    For example, instead of:

    it should be

    That should work for you (let me know if it doesn’t).

  • Karin

    Hi Jim,

    First of all great script, thank you.

    I have recently upgraded my Google Standard Analytics to Google Universal Analytics.

    How would I go about implementing this script using the new analytics? From what I can see, it looks to be a lot more complicated.

    Your thoughts?

    • @Karin –

      Instead of using _gaq.push like below:

      _gaq.push([‘_trackEvent’, ‘INSERT FORM NAME HERE’, ‘completed’, $(this).attr(‘name’)]);

      You ‘d need to pass the ga function the send command with the event hit type, like below:

      ga(‘send’, ‘event’, ‘INSERT FORM NAME HERE’, ‘completed’, $(this).attr(‘name’));

  • Joey


    I have a form on my website – but I want to measure a ‘Form Abandonment Rate’ as a percentage.

    That is, those who type something on my form but do not convert. So I want to measure the (# of successful conversions/# of abandonments).

    # of abandonments is anytime the type something on my form that’s only measure once. Assuming I have 3 fields (firstname, lastname, age) – then anytime they type something once any of those fields, but do not register, it’s count as an abandonment.

    Also, in GA, I have set up a Goal that measures the conversion of my form.

    Now, is it possible to set this up using GA – to see the numbers of Conversion Goals (which GA provides) and number of Abandonment – to create a percentage for Abandonment Rate?

  • @Joey –

    If you are tracking your form with the above script, you could create a custom advanced segment to include visits where Event Action contains “completed” (without the quotes).

    Then you can apply that segment and look at your Goal reports to see the conversion rate for that goal, and abandonment rate (if you’ve set up a funnel).

  • Siravut

    First off, thank you for this awesome code! I tried to adapt for forms I want to track.

    However, it doesn’t seem to work for multiple forms. It calls all of my forms even when the ‘INSERT FORM NAMES’ of the forms are different.

    Not sure what’s going on…

  • Joey

    Thanks – looking at the script, the abandonment is trigger everytime someone click a field in the form and then
    click elsewhere (the ‘blur’ event).

    However, what if someone click on the form and then just close their browser, or go to a different URL in the browser? Will that trigger
    an abandonment? If not, how can I change the script to make it work?

  • Siravut

    Hi Jim,

    I have multiple forms in a file so this code will select input of each form and says each is incomplete. Do you know a way to prevent that? Thanks!

  • I’m using the script on two separate pages with two different form names. I’m able to track the results well on the 1st page i.e.,

    However results are not tracked in the second page here

    though i’m using two different form names

    Any help/pointers for me where i’m doing wrong ?

  • @Joey –

    The event should still trigger even if they go to a different URL in the browser or close the tab/window. You may see situations where the event doesn’t fire (the browser closes before the event hit is sent – what we call the race condition) but I’ve seen the event fire on browser close in some very limited testing.

    @Siravut –

    I’m not sure I understand your question. Do you have multiple forms and only want the event tracking on one of the forms?

    @wedding dresses –
    Thank you. I’m glad you are very interested in this thing.

  • Wim

    Will the script work with drop-down lists included in the form?

  • Thanks for the explanation. I added this:

    to get the form id, use:

  • @Wim – yes – this will work dropdowns. The :input selector selects all input, textarea, select and button elements (pretty much anything you can throw in a form).

    @Marvin – great suggestion! Automation, FTW.

  • Deen37

    I have an issue with “skipped” events being fired two times when I am focused on the form and then switch over to lets say a Word Doc or another application. This only happens when I use Chrome and is not duplicated in IE10 or FireFox. Have you come across this issue? Is there a fix specific to Chrome? Please advise.

  • @Deen37 –

    That is normal (unfortunately). I’ve seen that behavior in Firefox and Chrome – IE is a little different. The .blur event doesn’t bubble in IE (although there’s a workaround by mapping blur to focusout as of version 1.4.2 of jQuery).

    Either way, it’s not ideal. I’ve been thinking about updating the script to only trigger the event if the cursor leaves one form input and enters another (as opposed to clicking somewhere out of the form or even out of the browser).

  • Rob

    Hi Jim: to be clear, the full code would look like this, right?:

    (function($) {
    $(document).ready(function() {
    $(‘:input’).blur(function () {
    if($(this).val().length > 0) {
    _gaq.push([‘_trackEvent’, ‘Checkout_Page’, ‘completed’, $(this).attr(‘name’)]);
    else {
    _gaq.push([‘_trackEvent’, ‘Checkout_Page’, ‘skipped’, $(this).attr(‘name’)]);

  • Rob

    With this above it:

    <script type=”text/javascript”

  • @Rob – That looks good to my eyes (although, it is the end of the day and my eyes aren’t as sharp as they were this morning, so be sure to test first!).

  • Venkatesh

    Thanks for your post

    I am having two questions.

    1. Consider if we are having 3 steps (3 different pages) to complete form.
    Is is ok to place the above code at the continue button of 1st and 2nd page to track the completed and skipped information from each page or its enough to place the code at 3rd page submit button only to track the completed and skipped information of pages 1,2,3.

    2.Will this code help me to track completed and skipped numbers/digits from the form text fields.

    Thanks for your help in advance

  • @Venkatesh –

    If you only put the code on the 3rd page, then you will not be able to see skipped form fields from the 1st or 2nd page. You’ll need to have the code on all three.

    To your second question – yes. This script uses the :input selector, which selects all input, textarea, select and button elements.

  • Venkatesh

    Thanks Jim 🙂

  • Venkatesh

    Consider my customer is registering into my website using their email id and also with the dedicated account number which i have provided to them.When the user is logging in to my website with their login credentials like (Email id and password) the dedicated account number which i have given to them will be carried in web session.Shall i fetch only this account number and send it to google analytics using the below code. Will GA allows this kind of tracking. If GA allows this tracking where should i call the below function.I will not track the Email id or PII information.


    Please let me know any other possible way to track the unique customer id (Which i gave to the customer)


  • Satyendra

    Can I use form id instead of form name

    (function($) {
    $(document).ready(function() {
    $(‘:input’).blur(function () {
    if($(this).val().length > 0) {
    _gaq.push([‘_trackEvent’, ‘INSERT FORM id HERE’, ‘completed’, $(this).attr(‘name’)]);
    else {
    _gaq.push([‘_trackEvent’, ‘INSERT FORM id HERE’, ‘skipped’, $(this).attr(‘name’)]);

  • @Satyendra –

    Sure – you can use the form ID as the event category. This is the best way to go if your forms have an ID (which they should) so you won’t have to hard code the event category manually.

  • @Venkatesh – the only thing I would change with your custom variable code would be to change it to a visitor-level custom variable instead of a session level. That way, if they come back to the site later without logging in, they are still tagged as customer 5345435 (as in your example).

    To do that, you just need to change the scope parameter (the last parameter of the method) from 2 to 1.

    As far as where to call the setCustomVar method, you’ll need to set it once the user logged in. Usually, you can add this as part of the form script, after validating the form fields. Depending on your specific implementation, you could also set it on the page the user is sent to after logging in (if all users are sent to a “My Dashboard” or user profile type of page after logging in, for example).

  • hi there,

    bit of a new question, but the code above is that all i need to add, or do i add

    _gaq.push([‘_trackEvent’, ‘Payment Page Customer Details’, ‘completed’, $(this).attr(‘firstName’)]);
    else {
    _gaq.push([‘_trackEvent’, ‘Payment Page Customer Details’, ‘skipped’, $(this).attr(‘firstName’)]);

    for each field on my form page



  • @Ryan – you just need to add the full code from the post (along with jQuery) once on the page – not for each form field. The code uses an event listener for interactions with any form fields, then dynamically adds the GA event tracking code.


  • qpidity

    Very much interested in applying your solution, only thing is it isn’t clear to me how to apply to a situation where we have multiple forms through our joomla site which we want to track. Each form has a unique form name, so not sure how to go about adjusting the code to suit. Grateful for any advice you can offer.

    Thanks in advance

  • @qpidity –

    Instead of manually entering the form name (like in the code from the post) you can use:


    So the full event tracking portion of the code would be:

    _gaq.push([‘_trackEvent’, $(this).closest(‘form’).attr(‘name’), ‘completed’, $(this).attr(‘name’)]);

    (thanks to Marvin in the comments for this tip!)

  • Sébastien Brodeur

    I believe, you should use $(this).parents instead of $(this).closest

  • @Sébastien –

    I’m curious to know why you would use .parents() – I think it may have unintended consequences.

    The .parents() method will return all of the ancestors as an object. This may work if you only have one form on the page, but would be more fragile (multiple forms on the page would break it).

    The .closest() method pulls in the first form element it finds as it travels up the DOM tree, which is the one you want anyway.

  • anil

    Thanks for giving valuable information,
    The above code given Hole page analytic’s,

    But i am creating one Webpage,In that page i can place two buttons
    I want to analyze that two buttons analytics using Google analytic’s?
    It’s possible using google analytics?
    if possible how can i do this one plz provide some code ans guidence

  • advantcomp

    Hey everyone, I wrote a jQuery plugin which helps automate tracking form abandonment and engagement. Check it out!

Contact Us.

Follow Us



We'll get back to you
in ONE business day.
Our Locations
THE FOUNDRY [map] LunaMetrics

24 S. 18th Street
Suite 100

Pittsburgh, PA 15203


4115 N. Ravenswood
Suite 101
Chicago, IL 60613


2100 Manchester Rd.
Building C, Suite 1750
Wheaton, IL 60187