Form Integrations
AttributionHub automatically detects and populates forms from 20+ platforms. No additional code is required — add hidden fields to your form, and the script fills them with attribution data.
How Form Population Works
AttributionHub uses a two-tier architecture for form population:
- Standard forms handler — a universal handler that discovers all
<form>,.form,[role="form"], and[data-form]elements on the page and populates their hidden fields. This covers the majority of platforms. - Specialized handlers — dedicated handlers for platforms that use iframes, SDK APIs, or cross-origin messaging. These run first and mark populated forms so the standard handler skips them.
The population flow on every page load:
- Specialized handlers run first (HubSpot iframes, Marketo SDK, Pardot, ActiveCampaign, Calendly, Typeform, Zoho, Jotform, Webflow, Contact Form 7)
- Each specialized handler marks forms it populates with
data-attrhub-populated - The standard forms handler runs last, skipping any already-populated forms
- A retry fires after ~500 ms for late-loading forms
- A MutationObserver watches for dynamically inserted forms (SPA support)
All handlers honour your field mapping — no handler hardcodes field names.
Standard Forms (Universal Handler)
Works with any platform that renders standard <form> + <input> elements in the page DOM. Add hidden fields with names matching your field mapping:
<form action="/submit" method="POST">
<!-- Your visible form fields -->
<input type="text" name="name" placeholder="Your Name" />
<input type="email" name="email" placeholder="Email" />
<!-- Attribution hidden fields -->
<input type="hidden" name="ah_lt_channel" />
<input type="hidden" name="ah_lt_source" />
<input type="hidden" name="ah_lt_medium" />
<input type="hidden" name="ah_lt_campaign" />
<input type="hidden" name="ah_lt_landing_url" />
<input type="hidden" name="ah_ft_channel" />
<input type="hidden" name="ah_ft_source" />
<input type="hidden" name="ah_visitor_id" />
<button type="submit">Submit</button>
</form>Platforms Covered by Standard Forms
Because these platforms all render standard <form> and <input> elements, they work out of the box with no dedicated handler:
| Category | Platforms |
|---|---|
| WordPress form plugins | Gravity Forms, WPForms, Ninja Forms, Formidable |
| CMS | PayloadCMS, Strapi, Contentful |
| CRM | Pipedrive, Salesforce Web-to-Lead |
| Email marketing | Mailchimp, ConvertKit, ActiveCampaign (standard embed) |
| Frameworks | React, Angular, Vue, Svelte |
| HubSpot (non-iframe) | Native HubSpot forms rendered as .hbspt-form |
| Marketo (non-SDK) | Standard Marketo .mktoForm elements in the page DOM |
For frameworks like React, Angular, and Vue, the script dispatches both change and input events to trigger framework reactivity. No special configuration is needed.
Custom Form Selectors
If your form platform uses non-standard containers, you can extend the default selectors:
window.attrhub = {
settings: {
formSelectors: [
".gform_wrapper form",
".mc-embedded-subscribe-form",
'form[action*="pipedrive.com"]',
".payload-form",
],
},
};Custom selectors are merged with the defaults (form, .form, [role="form"], [data-form]) and deduplicated. See Configuration for details.
Specialized Handlers
The following platforms require dedicated handlers because they use iframes, SDK APIs, or cross-origin messaging that the standard handler cannot reach.
HubSpot (Iframe Embeds)
HubSpot forms embedded via <script> tags that render inside cross-origin iframes are handled by a dedicated handler. It appends attribution data as URL parameters on the iframe src.
- In HubSpot, go to Properties > Create property
- Create properties matching your field mapping names (e.g.,
ah_lt_channel,ah_lt_source) - Add these properties as hidden fields in your HubSpot form
- AttributionHub detects HubSpot iframes (
iframe[src*="hsforms.com"],iframe[src*="hubspot.com"]) and injects the data
Non-iframe HubSpot forms (.hbspt-form) are handled by the standard handler.
Marketo (SDK and Iframe)
The Marketo handler covers two integration paths:
- MktoForms2 SDK — if
window.MktoForms2is present, the handler usesMktoForms2.whenReady()andmktoForm.addHiddenFields()to inject attribution via the official API - Iframe embeds — attribution data is appended as URL parameters on the iframe
src
Standard Marketo forms (.mktoForm) in the page DOM are handled by the standard handler.
Salesforce Pardot
Pardot forms are typically embedded as cross-origin iframes on pardot.com or salesforce-sites.com subdomains. The handler detects these iframes and injects attribution data as URL parameters.
Detected selectors: iframe[src*="pardot.com"], iframe[src*="go.pardot.com"], iframe[src*="salesforce-sites.com"].
Pardot form handler pages rendered as inline <form> elements are handled by the standard handler.
ActiveCampaign (Iframe Widget)
ActiveCampaign offers two embed modes:
- Standard embed (inline HTML forms) — handled by the standard handler
- Iframe widget mode (floating widget / modal forms on
activehosted.com) — handled by this dedicated handler, which injects URL parameters on the iframesrc
Calendly
Calendly widgets render inside iframes, so form fields inside them are inaccessible. The dedicated handler listens for calendly.event_scheduled postMessage events from the Calendly iframe and captures conversion data including:
- All attribution fields from your field mapping
calendly_event_uriandcalendly_invitee_uri
Requires the Calendly embed SDK (window.Calendly).
Typeform
For Typeform embedded forms:
- In your Typeform, go to Logic > Hidden Fields
- Add fields with names matching your field mapping
- The script populates hidden fields via
data-tf-hiddenattributes and iframe hash parameters
Zoho Forms
Zoho forms embedded via iframes are detected and populated with URL parameters. Add hidden fields in your Zoho Form with matching field names.
Jotform
Jotform embeds are cross-origin iframes hosted on jotform.com. The handler detects iframe[src*="jotform.com"] and appends attribution data as URL parameters.
Jotform’s rare “source code” embed mode (standard <form> elements) is handled by the standard handler.
Webflow
Webflow forms use standard <form> elements, so field population is handled by the standard handler. The dedicated Webflow handler adds conversion tracking for Webflow’s fetch-based form submission, which bypasses the normal submit event flow.
The handler watches for Webflow’s .w-form-done success indicator becoming visible after submission and fires conversion tracking.
Contact Form 7 (WordPress)
CF7 forms are standard .wpcf7-form elements, so field population is handled by the standard handler. The dedicated handler listens for CF7’s wpcf7mailsent custom DOM event to capture AJAX-based submissions for conversion tracking.
Add hidden fields to your CF7 form template:
[hidden ah_lt_channel]
[hidden ah_lt_source]
[hidden ah_lt_medium]
[hidden ah_lt_campaign]
[hidden ah_lt_landing_url]
[hidden ah_ft_channel]
[hidden ah_ft_source]
[hidden ah_visitor_id]Custom Field Mapping
All handlers honour settings.fieldMapping. If your form uses different field names, override the defaults:
<script>
window.attrhub = {
settings: {
fieldMapping: {
"latest.attribution.channelGroup": "my_custom_channel_field",
"latest.attribution.source": "lead_source",
"latest.attribution.campaign": "campaign_name",
},
},
};
</script>This maps AttributionHub’s internal field paths to your custom form field names. See Configuration for the full path reference.
Not Supported
Some platforms cannot be integrated due to fully isolated cross-origin restrictions:
| Platform | Reason |
|---|---|
| Drift / Intercom | In-chat forms are fully isolated — no DOM access |
| Google Forms | Fully cross-origin iframe — cannot inject params |
Troubleshooting
Fields not being populated
- Timing issue — the form might load after the script runs. AttributionHub retries after ~500 ms and watches for DOM changes, but if your form loads very late, it may be missed.
- Field name mismatch — ensure field names exactly match (case-sensitive). Use browser DevTools to inspect the field
nameattribute. - Platform not detected — if your form platform uses a non-standard container, add its CSS selector via
formSelectorsin your settings. - Enable logging — set
enableLogging: truein settings and check the browser Console for population messages.
Double population
AttributionHub prevents double population by stamping populated forms with data-attrhub-populated. If you see duplicate values, check that you are not manually calling the script’s population function in addition to the automatic flow.
Values not persisting on submit
Some form platforms clear field values before submission. Check if your form platform has a “preserve hidden field values” option. Webflow’s fetch-based submission is handled by a dedicated conversion tracker.
SPA navigation issues
AttributionHub watches for DOM changes via MutationObserver. Forms that are dynamically inserted into the page are automatically detected and populated. Already-populated forms are skipped on re-detection.