How to use Hidden Fields to Include your Current URL, Referring Page URL, and form names using one line of JavaScript

Tracking a form’s source through hidden fields.

<!–The Problem:–
I don’t know where my site visitors are sending their form submissions from. I have 2 forms on every page in my website. A small site with 7 pages makes it possible for a user to send a form from 14 unique interaction points. Who sent which message using which form on which page?

To track that would require extra logins and backtracking through Google Analytics and Google Tag Manager. Webflow does not support this feature natively either. Having this information on the fly already formatted into the spreadsheet with the rest of the form data will simply the process and make the data even more useful.

<!–The Solution:–

Add a unique identifier to each form that gets submitted with the rest of the data. This can be done with in plain html with a few additional attributes. But if you’re reusing your styling using symbols, you cannot type in a static value. You’ll be able to tell which form was used, but not which page it was used on. However, a single line of javaScript on each hidden field will provide the information you need.

<!–This post includes instructions on how to:–

  • Get Form’s Location on the page
  • Get The URL of the page it was sent from
  • Get The URL of the last page the user was on before visiting the page containing your form.

as if the fields were typed by the user themselves. They will show up in the Webflow dashboard and can be included in your notification emails. No knowledge of coding is needed and is a great introduction to the most basic of basic javaScript projects.

<!–It’s done in 4 steps:–

  1. Create a form,
  2. Insert “hidden” fields with an HTML embed,
  3. Create a “class” for the hidden fields,
  4. Then insert a few lines of JavaScript.

That’s it.

<!–Step 1–

Create a form.

It CAN be saved as a “symbol” used on multiple pages on your site.
You may also have additional differently styled forms (saved as their own symbol) with identical input field names for a later spreadsheet merge or different application.

Change each field name in your form to something simple that could make a good spreadsheet column header. It’s good habit to be consistent as many functions are case-sensitive. In my form I use

  • name
  • email
  • message

as the field names. Research shows that conversion rates are much much higher when site visitors don’t have to work too hard to talk to you. 3 fields is plenty for me for a contact form.

Change field names by selecting the field, then clicking the settings gear in the canvas, or select the FormBlock element (icon that has horizontal bars) and from the settings panel, and enter the field name there.

Note the difference in your form’s name, ID, and class. While you won’t need it for this setup, it’s helpful when searching your code when testing.

<!–Step 2–

Create hidden input fields as an HTML embed element
There’s a lot of info available about these HTML tags. Here’s the TL;DR version;

Copy and paste this into an HTML embed element and place it anywhere in the “Form” div.

	<input type="hidden" class="sourceLogging" id="hiddenKey01" name="formSrc1" data-name="formSrc1" value="modal">
	<input type="hidden" class="sourceLogging" id="hiddenKey02" name="formUrl1" data-name="formUrl1" value="">
	<input type="hidden" class="sourceLogging" id="hiddenKey03" name="formRef1" data-name="formRef1" value="">

Copy and paste this into an HTML embed element and place it anywhere in the “Form” div. It cannot just be in WebFlows “Form Block”. I placed mine right above the “Submit” button. At most you’ll see a thin horizontal blue line on your canvas as it will be not visually rendered by your browser at all.

If you have a second form location on your page, this is how the second embed code would look:

	<input type="hidden" class="sourceLogging" id="hiddenKey11" name="formSrc1" data-name="formSrc1" value="footer">
	<input type="hidden" class="sourceLogging" id="hiddenKey12" name="formUrl1" data-name="formUrl1" value="">
	<input type="hidden" class="sourceLogging" id="hiddenKey13" name="formRef1" data-name="formRef1" value="">

Note how everything was identical except the id=“” of each field changed because each must be unique. And of course, you can name the location of the 2nd form whatever you like. It’s just the string that will be included as the entry in your Webflow reports.


While words and data here won’t be rendered by the browser, any site visitor can simply view the page source and view your html, css and script. No more discliamers.



	name="[your UNIQUE name]" 		

for each field. Names MAY be re-used in other forms. See example above.

	id="[your VERY UNIQUE name]" 	

each field on the page. Names may NOT be re-used anywhere in the document. See example in step 3.

	data-name="[same string you used for name]" 	

Webflow does this for all their form fields.

	class="[a class name]" 		

that you want to assign to hidden fields. Not totally necessary to include here, but doesn’t hurt. SEE STEP 3A

	value="[data sent with form]"  

For the first field, name the form location you’ll identify later. The second two lines say value=“” …two-double quotes with no space in between. Do not change this. The script we insert will populate this data as it will change from page to page.

While styling an element that doesn’t get rendered may seem pointless, there may be additional use in the future using script to manipulate data throughout the page and form HTML is key to work and behave the way you want it to, so I put it in for good measure. IF YOU DO, INCLUDE THIS STEP…

<!–Step 3–

Copy and paste the javaScript code into your project.

		document.getElementById('hiddenKey02').value = location.pathname;
		document.getElementById('hiddenKey03').value = document.referrer;

Include it either sitewide from your project settings panel in the account dashboard, or on the pages tab inside the designer. Script is meant to run in the body, so do not insert it before the end of the tag. Insert it before the end of the tag.

I’m Happy to say this is the first code I wrote in JavaScript. Pretty easy. The code tells the browser to look in the document for an element that has an ID that matches what’s in the (‘quotes’) and assign a value attribute equal to the current page url (returned as /pagename for location.pathname) and the complete url of the referring page, or the last page in the browser history (returned as http://www… for document.referrer).

	document.getElementById('hiddenKey02').value = window.location.href;

can be substituted for

	document.getElementById('hiddenKey02').value = location.pathname; 

which will include the entire url starting with http://…
I prefer the simplified data to not need very wide columns to SEE the data in a spreadsheet and reduce file sizes etc. Include both… it’s your site, LOL.


The string you assigned to the fields in the HTML as the id=“[veryUniqueIDyouMakeUp]” must match the string inside the (‘’) of the JavaScript to work. Be case sensitive. You’re telling the script WHERE you want the information to be assigned. Each ID per page must be unique and cannot be reused. If you have two forms on your site, this is how the script would look:

	  document.getElementById('hiddenKey02').value = location.pathname;
	  document.getElementById('hiddenKey03').value = document.referrer;
	  document.getElementById('hiddenKey12').value = location.pathname;
	  document.getElementById('hiddenKey13').value = document.referrer;

The ID’s hiddenKey12 and hiddenKey13 are the field ID’s in the additional form.

<!–Step 3A–

If you include the class=“” attribute, for safe measure, do the following. Add a plain div block anywhere in your site. (above or below the embed element you just created would be a great choice. Set the height and width to 0, or set it to display:none. or add any attributes you like. Give it a class name that matches the name referenced in the HTML. This ensures when Webflow publishes your page, it includes the class in the .css file it generates.

<!–Step 4–


If you haven’t already done so, refer to existing documentation and save your form(s) as a symbol, so you can easily copy it to additional pages and make changes that update site-wide.

Save your settings. Save a backup. Publish your site. Forms get tested in a live environment. Try sending data from different forms from different pages on your site. Then check your dashboard for the entries, and any other automated notifications you have set up… You will see the data submit and report as if the user was typing in the data themselves in a regular field and is integrated into the form system seamlessly. So I don’t get confused when I’m sending myself so many tests, I like to include a 4 digit time stamp in the message body just because it’s easy to reference at a glance.

On my site, two forms post to a single google spreadsheet using google apps script. There’s links to documentation in the screencast I made of the demonstration working correctly. It’s free, and doesn’t need Zapier, and doesn’t need Webflow form service to work outside of regular server activities. My next steps are going to use Google API to take the form entries, and feed them back to me on a redirect page, so while entering customer information, I can “edit” or catch errors before submitting to a PDF template for invoicing, automated and timed emails in the process including reminder emails and summaries, and a few other neat tricks. If you have experience in this I’d love to see what you have set up.



Awesome, I was looking for just this. Thanks for the write up!

Good luck with it! When im back on my desktop I’ll post a combined simplified script that can all go in just the HTML embed in the form, including hidden field values AND google apps script call that writes your form data to a new row on a google spreadsheet (one thats secure and isnt published to the web or using google forms).

When making the sample page i realized that something more modular (“not” having that exact particular code on every published page) would be even more useful

Awesome! I can’t wait :slight_smile:

1 Like

You’re a life saver! This worked without having to outsource a developer!

Amazing! Somebody give you an award. I implemented in less than an hour with no previous JavaScript experience. You my friend are the best.

Me again, this is brilliant. I just built a bespoke recipe review system exclusively using this code all inside of Webflow.

You my friend are the bees knees!

Link if anyone is interested:

Would love to see what you’ve done as I’m looking to build in some reviews as well, but your link isn’t working. Got an updated one or anything you can share? Thanks

Hey there!
Unfortunately I can’t seem to get this working. The form comes in like this:

formSrc1: modal
formUrl1: /

I’ve tried embedding the javascript sitewide, as well as on the specific page, but it just won’t work. I’m not sure why. :frowning:

I tried this and I can see the form fields with the correct values, but it’s not being sent to Mailchimp with the API calls. Any ideas?

anyone here can guide me on how to track the URL of the first page seen by any lead which is coming in?

Requires custom code. You would need to use browser storage or a cookie that has a variable that was set upon page load containing the pathname. The code would need to check if the value existed, if not then set it. This variable could then be added to a form element as its value.

Okay thanks! Got it.

Not sure if this was a happy accident or normal behavior but a HubSpot integration shows the source of the form as well. Probably a total coincidence I was working both angles at the same time.

I am getting this too, did you ever manage to sort it out?

I found this solution helpful and simple to implement: Adding the Source or Page URL to Webflow Forms

Thank you for sharing, this provides a unique page link from the page where the user submitted the form. Thank you @Steve-K and @Nikolai_Bain

I am getting that too

Any chance to include these hidden fields in the payload of a webhook? Can’t figure out how to do that.