-
-
Save joziahg/b895c7791306802f43978932e9e38fd7 to your computer and use it in GitHub Desktop.
<!-- Header Code --> | |
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/shell.js"></script> | |
<!-- Footer Code --> | |
<!-- Minified use this in production --> | |
<script> | |
$('form[action^="https://api.hsforms.com"]').each((function(e){$(this).find("input[type=checkbox]").val("true"),$(this).submit((function(e){e.preventDefault();const n=[...new FormData(e.target).entries()].map((e=>({name:e[0],value:e[1]}))),t=n.find((e=>"goToWebinarWebinarKey"===e.name))?.value,i=n.find((e=>"sfdcCampaignId"===e.name))?.value,o=document.cookie.replace(/(?:(?:^|.*;\s*)hubspotutk\s*\=\s*([^;]*).*$)|^.*$/,"$1")||void 0;console.log(o);const s=$(this).find("[id*='gdpr-processing-prompt']"),a=n.filter((e=>e.name.includes("LEGAL_CONSENT"))).map((e=>{const n=$(`#${e.name.replace(/(:|\.|\[|\]|,|=|@)/g,"\\$1")}`)[0],t=$("span[for='"+$(n).attr("id").replace(/(:|\.|\[|\]|,|=|@)/g,"\\$1")+"']");return{value:n.checked,text:t.text(),subscriptionTypeId:parseInt(e.name.split("LEGAL_CONSENT.subscription_type_")[1])}})),r=["cc-num","cc-number","gdpr","LEGAL_CONSENT","goToWebinarWebinarKey","sfdcCampaignId"],c={fields:n.filter((e=>!r.find((n=>e.name.includes(n))))),context:{pageUri:window.location.href,pageName:document.title,sfdcCampaignId:i,goToWebinarKey:t,hutk:o},...s?{legalConsentOptions:{consent:{...s?{consentToProcess:!0,text:s.text()}:{},...a?{communications:a}:{}}}}:{}},l=JSON.stringify(c);$.ajax({url:e.target.action,method:"POST",data:l,contentType:"application/json",success:function(n){if(n)if(n.inlineMessage){const t=$(e.target).parent();t.children("form").css("display","none"),t.children(".w-form-done").css("display","block").html(n.inlineMessage)}else n.redirectUri&&(window.location.href=n.redirectUri);else console.log("response but no inlineMessage or redirectUri")},error:function(){console.log("error on the form submitting"),$(e.target).css("display","none").siblings(".w-form-fail").css("display","block")}})}))})); | |
</script> | |
<!-- Documented, dont use this in production. Copy and paste into a minifier to get the minified version above --> | |
<script type="text/javascript"> | |
$('form[action^="https://api.hsforms.com"]').each(function (i) { // intercept forms whos action goes to hubspot | |
$(this).find("input[type=checkbox]").val("true") | |
$(this).submit(function (e) { // when the form submits | |
e.preventDefault() //stop the form from submitting to webflow | |
const formData = new FormData(e.target) // get the form data | |
const parsedFormData = [...formData.entries()].map(dataObject => ({ // convert data to array | |
name: dataObject[0], // make sure the name of the input is the same as the hubspot input name | |
value: dataObject[1] // the value of the input | |
})) | |
const goToWebinarWebinarKey = parsedFormData.find(input => input.name === 'goToWebinarWebinarKey')?.value // looks for an input with the name goToWebinarWebinarKey | |
const sfdcCampaignId = parsedFormData.find(input => input.name === 'sfdcCampaignId')?.value// looks for an input with the name sfdcCampaignId | |
const hutk = document.cookie.replace(/(?:(?:^|.*;\s*)hubspotutk\s*\=\s*([^;]*).*$)|^.*$/, "$1") || undefined // looks for an input with the name hutk, the hubspot user token | |
console.log(hutk) | |
const processingPrompt = $(this).find("[id*='gdpr-processing-prompt']")// looks for an element with the id gdpr-processing-prompt | |
const communicationConsent = parsedFormData.filter(item => item.name.includes('LEGAL_CONSENT')).map(item => { // finds LEGAL_CONSENT options and stores them | |
const element = $(`#${item.name.replace(/(:|\.|\[|\]|,|=|@)/g, "\\$1")}`)[0] // checks if they've checked the checkbox to consent | |
const label = $("span[for='" + $(element).attr('id').replace(/(:|\.|\[|\]|,|=|@)/g, "\\$1") + "']") // gets the label of the checkbox | |
return { | |
value: element.checked, | |
text: label.text(), | |
subscriptionTypeId: parseInt(item.name.split("LEGAL_CONSENT.subscription_type_")[1]) // the subscription the user is consenting to | |
} | |
}) | |
const ignoredFields = ["cc-num", "cc-number", "gdpr", "LEGAL_CONSENT", "goToWebinarWebinarKey", "sfdcCampaignId"] | |
const data = { // the data we send to hubspot | |
"fields": parsedFormData.filter(item => !ignoredFields.find(ignoredField => item.name.includes(ignoredField))), // set the form data but ignore certain fields | |
"context": { | |
"pageUri": window.location.href, // log the current url | |
"pageName": document.title, // log the pages title | |
"sfdcCampaignId": sfdcCampaignId, // salesforce campaign id | |
"goToWebinarKey": goToWebinarWebinarKey, // go to meeting key | |
"hutk": hutk, // hubspot user token | |
}, | |
...(!processingPrompt) ? {} | |
: { | |
"legalConsentOptions": { | |
"consent": { | |
...(!processingPrompt) ? {} | |
: { | |
"consentToProcess": true, | |
"text": processingPrompt.text(), | |
}, | |
...(!communicationConsent) ? {} | |
: { | |
"communications": communicationConsent | |
} | |
} | |
} | |
} | |
} | |
const final_data = JSON.stringify(data) // turn that javascript object into a json string | |
$.ajax({ | |
url: e.target.action, | |
method: "POST", | |
data: final_data, | |
contentType: "application/json", | |
success: function (response) { | |
if (response) { | |
if (response.inlineMessage) { | |
const parent = $(e.target).parent() | |
parent.children("form").css("display", "none") // hide form | |
parent.children(".w-form-done").css("display", "block").html(response.inlineMessage) // replace .w-form-done with your own form done section | |
} else if (response.redirectUri) { | |
window.location.href = response.redirectUri | |
} | |
} else { | |
console.log('response but no inlineMessage or redirectUri') | |
} | |
}, | |
error: function () { | |
console.log("error on the form submitting") | |
$(e.target).css('display', 'none').siblings('.w-form-fail').css('display', 'block') // replace .w-form-fail with your own form done section | |
} | |
}) | |
}) | |
}) | |
</script> |
@arseniysij Interesting. I added a few comments in the code indicating users should replace the w-form-x
class with their own
You can now use salesforce campaign ids and go to meeting ids as hidden fields
Success message now takes content from hubspot instead of webflow
@joziahg thanks so much for your work on this! I've been able to successfully implement the code, and receive form submissions in HubSpot. How would you go about sending a cookie with the form so that it links with existing contacts in HubSpot? I have the HubSpot tracking code on our webflow site.
@Andrew-WRKOUT I updated the code to add another hidden input, hutk
similar to sfdcCampaignId
and goToWebinarKey
Just create a hidden input like so:
<input type="hidden" name="hutk" value="HUBSPOT_TRACKING_CODE">
@joziahg wow, thanks again for getting back to me so quickly! Forgive the stupid question, but do i have to change the value for the hidden input, or leave it as "HUBSPOT_TRACKING_CODE" ?
@Andrew-WRKOUT I updated the code again to send hubspot cookies. You could also use a hidden input like i mentioned before but it should just work now.
@joziahg really appreciate all your help. Unfortunately after changing the footer code to the updated one, the forms now fail to send submit...
Try now with the updated code
@joziahg just tried, and now it returns an Error 415 "unsupported media type" when i submit a form
@Andrew-WRKOUT I copied something wrong, it should work this time
Btw If you are collecting non hubspot forms with your tracker code you will want to place this on pages with forms using this custom code
<span id="CollectedForms-YOUR_HUBSPOT_PORTAL_ID"></span>
@joziahg Boom, the updated code indeed works, can't thank you enough!
If I could pick your far more knowledgable brain some more...do you mean i should include that span tag within an html embed in webflow, within the form?
I'm currently only connecting my webflow forms to ones that I've built in HubSpot, but will soon be utilizing non-hubspot forms as well. What's the purpose of including this span tag in that use case?
On each page hubspot looks for an element with that id, if it exists it doesn’t load the JavaScript to track non hs forms, like the ones created using this code.
it allows you to use the tracking code site wide but ignore manually created hubspot connected forms
Great! @joziahg
But I can't get this script working with dropdowns in Webflow such as 'Inbound Lead Source' or 'Company Size'. If I remove them and use regular text fields the submission is posted to Hubspot (Sales Hub Professional). Property names are matching and values as well (COMPANY.inbound_lead_source in Webflow).
Are there limitations, or should dropdowns work as well?
Hi. Didn't get this to work for some reason, nevertheless thank you for a great tutorial and the time spent creating this.
Would you be available for consulting/freelancing to help me, and also helping me setting up an additional thing that is related to this?
Update: Third attempt and now it is working like a charm. Thank you very much.
However, I didn't get it work along with Hubspot tracking code. Where exactly you mean I should embed the span code?
<span id="CollectedForms-YOUR_HUBSPOT_PORTAL_ID"></span>
Hey guys, I followed the tutorial and copied the header and footer codes but when I click submit on my webflow form it gives me this error. This error is usually there when contentType is not set to application/js. But seeing the above code contentType is being set to application/js. So why am I getting this error?
Thanks!
Any help on this? ^
you are probably missing header script
Added the script given above.
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/shell.js"></script>
Does this code work with a raw HTML form?
It does not bring information from hidden fields such as utm_source, utm_medium, utm_campaign, utm_content, utm_term, gclid, ruid, uid
Does this code work with a raw HTML form? It does not bring information from hidden fields such as utm_source, utm_medium, utm_campaign, utm_content, utm_term, gclid, ruid, uid
Yes, It should. I used raw HTML to test and develop it as I didn't have access to webflow codeblocks at the time.
As far as the hidden fields go, this wrapper should send those aswell. You'll want to make sure the field names are the same as whats in hubspot. If the value of the field doesn't belong to either Contact, Company, or a Custom Property already setup in hubspot I don't think it will work. It's been a while since I've worked on this so I can't say for sure right now
Hi there! Amazing stuff and I'm so close to getting it to work!!
The submissions are going through however the hidden fields aren't being populated.
I am getting this error on the submissions: The cookie needed to link form submissions to existing contacts isn't being sent. You'll need to ask your developer to update the integration for this form.
The hidden fields are being populated by another cookie we've implemented (Attributer.io).
Can you make out what's happening here? I'm not sure if it's a problem with the code, Hubspot or Attributer.io 🙁
Thanks!
Amazing bro thank you for this.
Hi @joziahg awesome job. Loaded up followed video instructions and bam worked like a treat. However as soon as I wanted to add a company field (ie. COMPANY.xxx) it through a 400 error. Little bit of digging showed that the COMPANY.xx no longer seems to work and you need to use 0-2/. Damn can't add / in Webflow as its automatically replaced with a hyphen.
Debosmit Ray on your Youtube vid commented that he added some footer code to modify the array
const parsedFormData=unprocessedParsedFormData.map(a=>"COMPANY.name"===a.name?{...a,name:"0-2/name"}:a);
When I go to add it and minify the code it throws an error. Not sure why. Any chance you can update the video/code to address this change?
Thanks, author.
Unfortunately, this doesn't work for me for the Webflow site. With and without hidden input - it doesn't send user cookie to HubSpot and creates separate contacts.
Is there any updates of the code up to date?
Appreciate
Success states weren't working, so I added lines starting with " $(e.target)".
success: function (t) {
console.log('successful email submitting');