Skip to content
English
  • There are no suggestions because the search field is empty.

How To Identify Users From HubSpot Forms

Identify Users from HubSpot Forms

Learn how to automatically identify website visitors when they submit a HubSpot form, enabling cross-device tracking and enriched visitor profiles in Lytical.

What this enables: When a visitor fills out a form (demo request, contact form, newsletter signup), Lytical will link their anonymous browsing history to their real identity. You'll see their name and email in the Identified Users report, and can track them across multiple devices and sessions.

Prerequisites

  • Lytical tracking code installed on your website
  • One or more HubSpot forms embedded on your site

Where to Add the Code

Add the integration script site-wide so it works on all pages with HubSpot forms. The code only fires when a HubSpot form is submitted, so it's safe to include everywhere.

HubSpot CMS

Go to Settings → Website → Pages → Site Footer HTML and paste the script there.

Google Tag Manager

Create a new Custom HTML tag, paste the script, and set it to fire on All Pages.

Other Platforms

Add the script to your site's footer template, after the Lytical tracking code. Make sure it loads on all pages where HubSpot forms appear.

Choose Your Integration Method

HubSpot has two form systems with different event APIs. Choose the method that matches your setup:

Method Best For Scope
Universal Script (Recommended) Works with both legacy and new (V4) forms Site-wide
V4 Global Events New form editor only (2024+) Site-wide
Legacy PostMessage Legacy form editor, iframe embeds Site-wide
JavaScript API Callback Forms via hbspt.forms.create() Per-form

Not sure which form type you have? Use the Universal Script — it listens for both legacy and V4 form events, so it will work regardless of which HubSpot form editor you used.

Method 1: Universal Script (Recommended)

This script listens for both legacy form events (hsFormCallback) and new V4 form events (hs-form-event), ensuring compatibility with any HubSpot form.

Why this is recommended: HubSpot has two different form systems with different event APIs. This script handles both, so you don't need to know which one you're using.

<script>
// Lytical + HubSpot Form Integration (Universal)
// Works with both legacy forms and new V4 forms

// Helper function to identify user
function lytIdentifyFromHubSpot(values) {
var email = values.email;
if (!email || typeof lyt === 'undefined') return;

// Auto-detect source from page URL
var source = 'hubspot_form';
if (location.pathname.includes('demo')) source = 'demo_request';
else if (location.pathname.includes('contact')) source = 'contact_form';
else if (location.pathname.includes('pricing')) source = 'pricing_inquiry';
else if (location.pathname.includes('newsletter')) source = 'newsletter_signup';

lyt.identify(email, {
email: email,
name: [values.firstname || '', values.lastname || ''].filter(Boolean).join(' '),
phone: values.phone || '',
company: values.company || '',
source: source
});

console.log('[Lytical] Identified user:', email);
}

// V4 Forms (new form editor)
window.addEventListener('hs-form-event:on-submission:success', function(event) {
if (!window.HubSpotFormsV4) return;

var form = HubSpotFormsV4.getFormFromEvent(event);
if (!form) return;

form.getFormFieldValues().then(function(fields) {
var values = {};
fields.forEach(function(field) {
// Clean field names (remove prefixes like "0-1/")
var name = field.name.replace(/^[\d]+-[\d]+\//, '');
values[name] = Array.isArray(field.value) ? field.value[0] : field.value;
});
lytIdentifyFromHubSpot(values);
});
});

// Legacy Forms (older form editor, iframes, HubSpot CMS)
window.addEventListener('message', function(event) {
if (event.data.type === 'hsFormCallback' &&
event.data.eventName === 'onFormSubmitted') {
var values = event.data.data.submissionValues || {};
lytIdentifyFromHubSpot(values);
}
});
</script>

Copy and paste this entire script into your site footer. It automatically detects the form source based on the page URL, but you can customize the source detection logic to match your site structure.

Method 2: V4 Global Form Events

If you're only using forms created with HubSpot's new form editor (2024+), you can use the newer hs-form-event API.

How to tell if you have V4 forms: If your form embed code looks like <script src="https://js.hsforms.net/forms/embed/v4/..."> or uses class="hs-form-frame", you have V4 forms.

<script>
window.addEventListener('hs-form-event:on-submission:success', function(event) {
var form = HubSpotFormsV4.getFormFromEvent(event);
if (!form) return;

form.getFormFieldValues().then(function(fields) {
var values = {};
fields.forEach(function(field) {
var name = field.name.replace(/^[\d]+-[\d]+\//, '');
values[name] = Array.isArray(field.value) ? field.value[0] : field.value;
});

var email = values.email;
if (email && typeof lyt !== 'undefined') {
lyt.identify(email, {
email: email,
name: [values.firstname || '', values.lastname || ''].filter(Boolean).join(' '),
phone: values.phone || '',
company: values.company || '',
source: 'hubspot_form'
});
}
});
});
</script>

Available V4 Events

Event When It Fires
hs-form-event:on-ready Form has finished loading and rendering
hs-form-event:on-submission:success Form submitted successfully (use this one)
hs-form-event:on-submission:failed Form submission failed
hs-form-event:on-interaction:navigate Multi-step form navigation

Method 3: Legacy PostMessage Listener

For forms created with HubSpot's legacy form editor, or forms embedded in iframes, use the hsFormCallback postMessage event.

How to tell if you have legacy forms: If your form embed code uses hbspt.forms.create() or the embed version is v2/v3, you have legacy forms.

<script>
window.addEventListener('message', function(event) {
// Only process HubSpot form submission events
if (event.data.type === 'hsFormCallback' &&
event.data.eventName === 'onFormSubmitted') {

var values = event.data.data.submissionValues || {};
var email = values.email;

if (email && typeof lyt !== 'undefined') {
lyt.identify(email, {
email: email,
name: [values.firstname || '', values.lastname || ''].filter(Boolean).join(' '),
phone: values.phone || '',
company: values.company || '',
source: 'hubspot_form'
});
}
}
});
</script>

Available Legacy Events

eventName When It Fires
onBeforeFormInit Before form construction
onFormReady After form renders in DOM
onBeforeFormSubmit Start of submission (has field data)
onFormSubmitted After HubSpot accepts submission (use this one)

Method 4: JavaScript API Callback

If you're embedding HubSpot forms using their JavaScript API (hbspt.forms.create()), you can add the onFormSubmitted callback directly to your embed code.

Note: This method is per-form — you'll need to add the callback to each hbspt.forms.create() call. For site-wide coverage without modifying each form, use the Universal Script instead.

hbspt.forms.create({
portalId: "YOUR_PORTAL_ID",
formId: "YOUR_FORM_ID",
onFormSubmitted: function($form, data) {
var values = data.submissionValues || {};
var email = values.email;

if (email && typeof lyt !== 'undefined') {
lyt.identify(email, {
email: email,
name: [values.firstname || '', values.lastname || ''].filter(Boolean).join(' '),
phone: values.phone || '',
company: values.company || '',
source: 'demo_request'
});
}
}
});

Available Embed Callbacks

Callback Parameters Notes
onFormReady $form After form renders
onBeforeFormSubmit $form, submissionValues Before submission (preferred over onFormSubmit)
onFormSubmitted $form, {redirectUrl, submissionValues} After HubSpot accepts (use this one)

How It Works

  1. Visitor browses your site — Lytical tracks their pageviews, clicks, and behavior anonymously
  2. Visitor submits a HubSpot form — The script captures their email, name, and other fields
  3. Identity is created — Lytical links all their previous anonymous activity to their real identity
  4. Cross-device tracking begins — If they visit from another device and submit a form with the same email, both devices are linked to the same identity

Viewing Identified Users

Once users are identified, you can view them in Lytical:

  1. Go to Analytics in the left sidebar
  2. Click Identified Users under the Data section
  3. You'll see a list of all identified users with their email, devices, sessions, and pageviews
  4. Click on any user to see their profile, custom properties, and complete activity history
  5. Click View Devices to see all browsers/devices linked to that user

Captured Fields

The default script captures these standard HubSpot form fields:

HubSpot Field Lytical Property
email email (also used as identifier)
firstname + lastname name
phone phone
company company (stored in custom properties)
source source (auto-detected from URL)

Adding Custom Fields

If your HubSpot forms have custom fields you want to capture, modify the identify call to include them. Any field not in the standard list will be stored as a custom property:

lyt.identify(email, {
email: email,
name: [values.firstname || '', values.lastname || ''].filter(Boolean).join(' '),
phone: values.phone || '',
company: values.company || '',

// Add your custom fields here:
job_title: values.jobtitle || '',
industry: values.industry || '',
company_size: values.company_size || '',

source: 'demo_request'
});

The field names must match your HubSpot form field internal names. You can find these in HubSpot under Forms → Edit Form → click on a field → "Internal name". Custom properties appear in the user's profile when you click into their Identity Detail page.

Troubleshooting

Users aren't appearing in Identified Users

  • Verify the Lytical tracking code loads before the identify script
  • Check that your form has an email field (required for identification)
  • Open browser DevTools → Console and look for [Lytical] Identified user: messages
  • Check the Network tab for requests to i.lytical.ai after form submission

Testing the integration

  1. Open your website in an incognito/private browser window
  2. Open DevTools → Console before submitting the form
  3. Browse a few pages to generate anonymous activity
  4. Submit a form with a test email address
  5. Look for [Lytical] Identified user: test@example.com in the console
  6. Wait 1-2 minutes, then check the Identified Users page in Lytical

No console message appears

If you don't see the [Lytical] Identified user message, the form event isn't being captured. Try these steps:

  • Make sure you're using the Universal Script (Method 1) which handles both form types
  • Check that the script is in your site footer and loads on all pages
  • Verify there are no JavaScript errors in the console before form submission

Form values are empty or undefined

If the identify call fires but field values are empty, your HubSpot field names may be different. Add console.log(values) before the identify call to see what field names HubSpot is using, then update your script to match.

Why doesn't the DOM submit listener work?

HubSpot forms intercept the native form submit event and handle submission via AJAX. By the time a document.addEventListener('submit') fires, HubSpot has already processed and potentially cleared the form. That's why we use HubSpot's own event system (hsFormCallback or hs-form-event) instead.

 Need help? If you're having trouble with the integration, reach out to our support team and we'll help you get it set up. Email support@lytical.ai