Track Forms Without Thank You Pages Using GTM



Goal Funnels in Google Analytics are great. They allow you to track the progress your users make toward a Goal completion, with defined steps leading up to a final conversion. You can see where your users fall out of the funnel, and focus your efforts on those troublesome steps. Over time you can improve conversion rates by focusing on the leaky parts of your Goal Funnels.

Goal Funnel

But Goal Funnels require you to set distinct URLs for each and every funnel step. Each step needs its own URL and, well… that’s not that always easy.

Let’s suppose that you have a form that submits back to itself: the form on /contact goes back to /contact. And let’s suppose that you want to track this form completion in Google Analytics.


Let’s take a look at the website. This page contains a form that posts back to itself when it is submitted:


Let’s take a look at the code on the page.


There’s a simple HTML form here with an action attribute, which points back to the same page, /contact.

Best Solution:

Ideally, we’d just have our developers modify this form code, and have the action go to /contact?thankyou=1. This “fake” query parameter doesn’t tell the server to do anything, so it wouldn’t change the way the page looks or functions. Then we could distinguish between pages in our Goal Funnel steps!

Buuuuut your developers are on another continent, and the job needs to be done immediately! Your boss is demanding this was done yesterday, and the costs are already soaring! What can you do?!

Immediate Solution:

Disclaimer: This method only works if your form actually reloads the page; it will not work with “Ajax” forms that submit without reloading the page.

Pop open Google Tag Manager. We’ll create a new Custom HTML tag and dynamically rewrite the Form’s action attribute.

Step 1. Click “New” to create a new Tag.


Step 2. Name it “HTML – Dynamic Form Action Swap”, or something similar. Choose “Custom HTML” as the Tag Type.


Step 3. Go back to your website and find the form id of your particular form. For ours, it’s contactForm.


Step 4. Then, using jQuery, we can target that specific form:


This code rewrites the form and tells it to post to the same page with ?thankyou=1 at the end. It grabs the form action, stores it in a variable, and then rewrites the action with the appended dummy query parameter. And it’s all dynamic. (Pretty cool!)

(If this is throwing errors, perhaps your site doesn’t use the $ selector but uses jQuery or another selector instead. Just swap that in above.)

Step 5. Add a Trigger that will fire just on the page we need.


Step 6. Preview, Test, and Publish!

Step 7. Now create the Goal Funnel inside Google Analytics. Go into Google Analytics, click into the Admin, look under the correct View, choose Goals, and add a New Goal. Choose Custom, and then fill out the Goal like so:


And that’s it! Seriously!


Beautiful! Now to work on that conversation rate…

Yikes... what a conversion rate!


Q: What if my form doesn’t have an id?
A: Does your form have a class? Let’s pretend it has a class called contactFormClass:

Q: What if I don’t have a class?
A: Does your form have a name? Maybe it has a name called contactFormName:

Q: No, seriously. There’s no id or class or name or anything.
A: You can select the form based on the action itself:

Q: What if my website doesn’t have jQuery?
A: You can easily accomplish this exact same technique without jQuery, using vanilla JavaScript. (In fact, you might even prefer to.) Let’s pretend the form id is contactForm again:

Q: What if my website doesn’t have Google Tag Manager?
A: Well then, you’re going to have to make a change to the page’s code itself. In that case you’d be better off using the “Best Solution” option above. (And seriously, isn’t it time to upgrade to Google Tag Manager?)

Alex Moore is Vice President of our Analytics & Insight practice. He started building websites in the late-90s, and has spent over ten years in agencies, focused on front-end development, SEO/SEM, and of course web analytics. He also leads trainings in Google Analytics and Tag Manager around the country. Alex received his master's degree in Dublin, where he explored the Irish coast with a furry dog and lots of pints.

  • Peter Cooper

    Great tutorial, my client has website and contact form hasn’t thank you page. How can I set up adwords tracking for this contact form?

    • Alex Moore

      Hi Peter,

      Great question. With this method, you’ll be directing your traffic to a page with “?thankyou=1” at the end. Then it’s as simple as creating a new Trigger inside GTM that looks for “Some Page Views” where the Page URL equals this new URL with “?thankyou=1”. See screenshot below.

      With the Trigger created, you’ll be able to create a new AdWords tag (or any tag you like) and set it to fire on the new Trigger. Make sense?

  • Hi Alex,

    Very fine guide you made – thank you for that!

    However, I have a little problem:
    I have a website with about 20 different forms, but none of them sends the user to a thank you page. None!

    All forms are the same, and yet – they are unique. The unique feature can *ONLY* be seen when the form *HAS* been sent: there will be a thank-text and this text has a unique div-ID.

    How should/could I set this scenaria?

    • Alex Moore

      Sounds like you have a pretty complex situation!

      I’d recommend that you proceed with appending the “?thankyou=1”, as outlined in my post. Then you’ll need to create a Variable that looks for the “thank you text” div on the page and returns the ID of that div. THEN, based on this ID, you can DELAY the GA Pageview tag to fire on DOM ready WITH a rewritten virtual pageview with an additional query parameter representing the div ID. It would look approximately like this (see 3 screenshots):

      • Thanks Alex,

        – but I can’t make it fire. I think the deep problem is, that the page does not reload after sumbitting the form…

        You are welcome to see the form on this testpage:

        • Alex Moore

          Ahh, perhaps I should have called this out explicitly in the post: my solution only works for forms that actually reload the page upon submission. I’ll add that disclaimer.

          If you have an ajax form (a form that submits without reloading the page), you’ll need to use a custom solution, like putting a dataLayer.push({“event”:”form-submitted”}) in the JavaScript after the form validation. In that case you would create a Trigger that looks for that Custom event. Does that make sense?

          • Yeah – that makes sense. I’ll ask my developer to have a look into this (it’s out of my hands).

            Thanks for your time – much appreciated!!

  • Cesar Florero

    Hi Alex,

    I was able to make it work using form ID. My form page does reload after clicking on submit. How can I add more than one form ID to the custom HTML tag? I have a couple of forms on my site that have different form IDs or should I create unique custom HTML tags for each unique form ID?

    I would really appreciate your feedback.

    • Alex Moore

      Great question. While you *could* technically create a whole other Custom HTML tag, with its own firing trigger for just that page and that form id, I’d recommend you simply use the code you have, but add another jQuery selector for a second id. To do that, you write:
      (“#contactForm, #contactForm2”).attr(“action”, formAction + extraParameter);

      Because “formAction” comes from #contactForm (in my example), you’ll also want to update it with the appropriate action for this second form. You might need an if statement, to check for the existence of that second id, and if so to populate the “formAction” variable.

      • Cesc_Flo

        Hi Alex,

        Thank your for your quick response. This is very helpful. I am not much of a coder, but I can follow what you are suggesting here. Does adding the “if statement” line of code a must? otherwise, I could update the HTML tag per your instructions and it should work, correct?

        Thanks again,


  • Richard Linklater

    Hi Alex,

    Like you solution, but would like to use it as an event. Would something like the below work as a custom HTML?

    $(document).ready(function() {

    $( “form[action=’/contact-us/brochure-request/’]” ).submit(function( event )
    {ga(‘send’, ‘event’, ‘brochure request’, ‘submit’, ‘/contact-us/brochure-request/’);


    Would this send an event to GA?

    Any advice would be helpful.



  • Beth

    Thanks Alex.

    This was super easy to follow and it’s working well on my site. However, is there a way to only load the thank you page when the form is completely filled out? The thank you page loads when you receive an error page stating not all required fields were filled out.

    Any advice would be appreciated.

  • Pah Pin Shang

    Hi there,

    Am I did it correctly? Can you verify this for me?

    The contact page is

    And the GTM is as follow.

    $(document).ready(function() {
    var formAction = $(“#contact-form”).attr(“action”);
    var queryExists = formAction.indexOf(“?”) > -1;
    var extraParameter = queryExists ? “&thankyou=1” : “?thankyou=1”;
    $(“#contact-form”).attr(“action”, formAction + extraParameter);

    Seem like I did wronly, it did not record the new pageview.

  • Hey ! I am thankful for the info – Does anyone know where I could possibly get a fillable Smart Recovery Meeting Attendance Verification version to fill in ?

    • Ava Cueto1

      Greetings robbie henley. my partner filled out a sample NY DOS 0036-a form with this link

  • bhola prasad

    Hi Alex, I am trying to create a form tracking but I am having a problem. Can you help me with this ? The problem is my id is not constant. The begining few characters are constant but the later characters are keep changing again and again. Like – 1. yui_3_17_2_1_1472837316033_380
    2. yui_3_17_2_1_1472833812034_735
    3. yui_3_17_2_1_1472838339489_348
    4. yui_3_17_2_1_1472838380065_734 and so on
    what I need to do to configure it on GTM ?

    Thanks for reading this. Hope you have a great day.

  • Ondra

    And what if the form has more steps? Can I somehow use this solution?

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