Usermaven
Dark mode

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> element

  • You 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

track('$form', {...})

Forms section in dashboard

Form submissions you want to manage, map fields, and convert to leads

track('custom_event', {...})

Custom Events section

Thank you page tracking, conversion tracking, or when you only need basic event data

lead({...})

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:

  1. Go to Tags > New

  2. Choose Custom HTML as the tag type

  3. 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

  1. Go to Triggers > New

  2. Choose Form Submission as the trigger type

  3. 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

  1. Go to Variables > New

  2. Choose DOM Element as the variable type

  3. Set selection method to CSS Selector

  4. Enter the selector (e.g., #email or input[name="email"])


Best practices

  1. Choose the right method: Use $form for forms you want to manage in the Forms section, lead() for direct lead creation, and custom events for simple conversion tracking

  2. Always validate before tracking: Ensure form data is valid before sending

  3. Don't track sensitive data: Avoid capturing passwords, credit cards, or SSNs

  4. Use descriptive names: Make forms easy to identify in your dashboard

  5. Track on success: Only track when the form submission actually succeeds

  6. Include context: Add properties like source_page or campaign for better analysis


What's next?

Was this article helpful?