Manual Form Tracking
When automatic form tracking doesn't capture your forms—such as AJAX forms, iframe forms, or custom implementations—you can use manual tracking methods to send form data to Usermaven.
Before you begin
Usermaven tracking script is installed on your website
You have identified forms that aren't being automatically captured
When to use manual tracking
Use manual form tracking when:
Forms submit via AJAX without a page reload
Forms are embedded in iframes
Forms use custom JavaScript submission handlers
Forms don't have a standard
<form>elementYou need to track form submissions on a thank you page
You're using Google Tag Manager for tracking
Understanding form tracking options
Usermaven provides two ways to manually track form submissions:
Method | Where it appears | Best for |
|---|---|---|
| Forms section in dashboard | Form submissions you want to manage, map fields, and convert to leads |
| Custom Events section | Thank you page tracking, conversion tracking, or when you only need basic event data |
| Contacts Hub as leads | Directly creating leads from form submissions |
Method 1: Track forms in the Forms section
Use the $form event type to send form submissions that appear in the Forms section of your dashboard. This allows you to manage forms, map fields to contact properties, and convert submissions to leads.
Basic form tracking
JavaScript Snippet
<script>
document.getElementById('contact-form').addEventListener('submit', function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
// Track form submission (appears in Forms section)
window.usermaven('track', '$form', {
form_id: form.id || 'contact-form',
form_name: form.name || 'Contact Form',
form_action: form.action || window.location.href,
form_method: form.method || 'post',
form_class: form.className || '',
fields: [
{
tag: 'input',
type: 'email',
name: 'email',
value: formData.get('email')
},
{
tag: 'input',
type: 'text',
name: 'name',
value: formData.get('name')
},
{
tag: 'textarea',
name: 'message',
value: formData.get('message')
}
]
});
// Submit the form or handle AJAX submission
form.submit();
});
</script>
NPM Package
const usermaven = usermavenClient({
key: 'YOUR_API_KEY',
trackingHost: 'https://events.usermaven.com'
});
document.getElementById('contact-form').addEventListener('submit', function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
// Track form submission (appears in Forms section)
usermaven.track('$form', {
form_id: form.id || 'contact-form',
form_name: form.name || 'Contact Form',
form_action: form.action || window.location.href,
form_method: form.method || 'post',
form_class: form.className || '',
fields: [
{
tag: 'input',
type: 'email',
name: 'email',
value: formData.get('email')
},
{
tag: 'input',
type: 'text',
name: 'name',
value: formData.get('name')
},
{
tag: 'textarea',
name: 'message',
value: formData.get('message')
}
]
});
// Submit the form or handle AJAX submission
form.submit();
});
React / Next.js
function ContactForm() {
const { track } = useUsermaven();
const handleSubmit = (e) => {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
// Track form submission (appears in Forms section)
track('$form', {
form_id: 'contact-form',
form_name: 'Contact Form',
form_action: '/api/contact',
form_method: 'post',
form_class: '',
fields: [
{
tag: 'input',
type: 'email',
name: 'email',
value: formData.get('email')
},
{
tag: 'input',
type: 'text',
name: 'name',
value: formData.get('name')
},
{
tag: 'textarea',
name: 'message',
value: formData.get('message')
}
]
});
// Handle form submission
};
return (
<form id="contact-form" onSubmit={handleSubmit}>
<input type="email" name="email" required />
<input type="text" name="name" />
<textarea name="message"></textarea>
<button type="submit">Submit</button>
</form>
);
}
$form event payload structure
The $form event expects the following payload structure to properly appear in the Forms section:
{
form_id: 'unique-form-id', // Form's ID attribute
form_name: 'Contact Form', // Form's name or descriptive title
form_action: '/api/submit', // Form's action URL
form_method: 'post', // Form's method (get/post)
form_class: 'contact-form', // Form's CSS classes (optional)
form_attributes: {}, // Custom data attributes (optional)
fields: [ // Array of form fields
{
tag: 'input', // HTML tag (input, select, textarea)
type: 'email', // Input type (for input elements)
id: 'email', // Field's ID attribute
name: 'email', // Field's name attribute
value: 'user@example.com', // Field value
class: '', // Field's CSS classes (optional)
data_attributes: {} // Custom data attributes (optional)
}
]
}
AJAX form tracking
For forms that submit via AJAX, track after a successful response:
JavaScript Snippet
<script>
document.getElementById('ajax-form').addEventListener('submit', async function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: formData
});
if (response.ok) {
// Track successful submission (appears in Forms section)
window.usermaven('track', '$form', {
form_id: form.id,
form_name: 'Demo Request Form',
form_action: '/api/submit',
form_method: 'post',
fields: [
{ tag: 'input', type: 'email', name: 'email', value: formData.get('email') },
{ tag: 'input', type: 'text', name: 'company', value: formData.get('company') },
{ tag: 'input', type: 'text', name: 'name', value: formData.get('name') }
]
});
alert('Form submitted successfully!');
}
} catch (error) {
console.error('Form submission failed:', error);
}
});
</script>
NPM Package
document.getElementById('ajax-form').addEventListener('submit', async function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: formData
});
if (response.ok) {
// Track successful submission (appears in Forms section)
usermaven.track('$form', {
form_id: form.id,
form_name: 'Demo Request Form',
form_action: '/api/submit',
form_method: 'post',
fields: [
{ tag: 'input', type: 'email', name: 'email', value: formData.get('email') },
{ tag: 'input', type: 'text', name: 'company', value: formData.get('company') },
{ tag: 'input', type: 'text', name: 'name', value: formData.get('name') }
]
});
alert('Form submitted successfully!');
}
} catch (error) {
console.error('Form submission failed:', error);
}
});
React / Next.js
function DemoRequestForm() {
const { track } = useUsermaven();
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: formData
});
if (response.ok) {
// Track successful submission (appears in Forms section)
track('$form', {
form_id: 'demo-request-form',
form_name: 'Demo Request Form',
form_action: '/api/submit',
form_method: 'post',
fields: [
{ tag: 'input', type: 'email', name: 'email', value: formData.get('email') },
{ tag: 'input', type: 'text', name: 'company', value: formData.get('company') },
{ tag: 'input', type: 'text', name: 'name', value: formData.get('name') }
]
});
}
} catch (error) {
console.error('Form submission failed:', error);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
<input type="text" name="company" />
<input type="text" name="name" />
<button type="submit">Request Demo</button>
</form>
);
}
Method 2: Convert form submissions to leads
If you want to directly create leads from form submissions, use the lead() function. This creates a contact in your Contacts Hub with the provided information.
JavaScript Snippet
<script>
document.getElementById('lead-form').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(e.target);
// Create a lead directly (appears in Contacts Hub)
window.usermaven('lead', {
email: formData.get('email'), // Required
first_name: formData.get('first_name'),
last_name: formData.get('last_name'),
company: formData.get('company'),
phone: formData.get('phone'),
custom: {
source: 'website_form',
form_name: 'Newsletter Signup'
}
});
});
</script>
NPM Package
document.getElementById('lead-form').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(e.target);
// Create a lead directly (appears in Contacts Hub)
usermaven.lead({
email: formData.get('email'), // Required
first_name: formData.get('first_name'),
last_name: formData.get('last_name'),
company: formData.get('company'),
phone: formData.get('phone'),
custom: {
source: 'website_form',
form_name: 'Newsletter Signup'
}
});
});
React / Next.js
function NewsletterForm() {
const { lead } = useUsermaven();
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
// Create a lead directly (appears in Contacts Hub)
lead({
email: formData.get('email'), // Required
first_name: formData.get('first_name'),
last_name: formData.get('last_name'),
company: formData.get('company'),
phone: formData.get('phone'),
custom: {
source: 'website_form',
form_name: 'Newsletter Signup'
}
});
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="email" required />
<input type="text" name="first_name" />
<input type="text" name="last_name" />
<input type="text" name="company" />
<input type="tel" name="phone" />
<button type="submit">Subscribe</button>
</form>
);
}
Track form AND create lead
You can combine both methods to track the form submission in the Forms section and create a lead:
document.getElementById('demo-form').addEventListener('submit', function(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const email = formData.get('email');
// 1. Track form submission (appears in Forms section)
window.usermaven('track', '$form', {
form_id: form.id,
form_name: 'Demo Request',
form_action: form.action,
form_method: 'post',
fields: [
{ tag: 'input', type: 'email', name: 'email', value: email },
{ tag: 'input', type: 'text', name: 'company', value: formData.get('company') }
]
});
// 2. Create lead (appears in Contacts Hub)
window.usermaven('lead', {
email: email,
first_name: formData.get('first_name'),
company: formData.get('company'),
custom: {
demo_requested: true
}
});
});
Learn more about Lead Tracking →
Method 3: Custom event tracking (Thank you pages)
For simple conversion tracking on thank you pages or when you only need basic event data, use custom events. These appear in the Custom Events section, not the Forms section.
Thank you page tracking
Add this script to your thank you page to track conversions:
<script>
window.usermaven = window.usermaven || [];
// Track as a custom event (appears in Custom Events section)
window.usermaven('track', 'form_submitted', {
form_name: 'Contact Form',
source_page: document.referrer
});
</script>
With URL parameters
If form data is passed via URL parameters on the thank you page:
<script>
window.usermaven = window.usermaven || [];
const urlParams = new URLSearchParams(window.location.search);
window.usermaven('track', 'demo_requested', {
form_name: 'Demo Request',
email: urlParams.get('email'),
company: urlParams.get('company'),
source: urlParams.get('utm_source')
});
</script>
Method 4: Google Tag Manager (GTM)
Use Google Tag Manager to track form submissions without modifying your website code.
Option A: Track in Forms section
To have GTM-tracked forms appear in the Forms section:
Go to Tags > New
Choose Custom HTML as the tag type
Add the following code:
<script>
window.usermaven = window.usermaven || [];
window.usermaven('track', '$form', {
form_id: '{{Form ID}}',
form_name: '{{Form ID}}',
form_action: '{{Page URL}}',
form_method: 'post',
fields: [
{ tag: 'input', type: 'email', name: 'email', value: '{{Form Email Field}}' },
{ tag: 'input', type: 'text', name: 'name', value: '{{Form Name Field}}' }
]
});
</script>
Option B: Track as custom event
For simple conversion tracking:
<script>
window.usermaven = window.usermaven || [];
window.usermaven('track', 'form_submitted', {
form_name: '{{Form ID}}',
page_url: '{{Page URL}}'
});
</script>
Setting up GTM triggers
Go to Triggers > New
Choose Form Submission as the trigger type
Configure:
Wait for Tags: Enable to capture form data
Check Validation: Enable for successful submissions only
Fire on: All Forms or specific forms
Capturing field values in GTM
Go to Variables > New
Choose DOM Element as the variable type
Set selection method to CSS Selector
Enter the selector (e.g.,
#emailorinput[name="email"])
Best practices
Choose the right method: Use
$formfor forms you want to manage in the Forms section,lead()for direct lead creation, and custom events for simple conversion trackingAlways validate before tracking: Ensure form data is valid before sending
Don't track sensitive data: Avoid capturing passwords, credit cards, or SSNs
Use descriptive names: Make forms easy to identify in your dashboard
Track on success: Only track when the form submission actually succeeds
Include context: Add properties like
source_pageorcampaignfor better analysis
What's next?
Managing Forms - Configure field mappings for tracked forms
Lead Tracking - Convert form submissions to leads
Troubleshooting - Solve common form tracking issues
Was this article helpful?