How do I set up an Adobe Launch rule that reliably tracks form submissions and clicks?

Quick answer

Use Launch's Core "Form Submitted" trigger for forms and Core "Click" trigger for buttons and links - both exist specifically so you don't hand-write DOM listeners - and scope each rule's condition to a specific selector rather than "all forms" or "all clicks" on the page. The reliability problems people hit are almost always scope (the rule matches too much or too little) or timing (the form validates and redirects before the rule's action finishes), not the trigger mechanism itself.

Why this happens

Launch's Core extension ships dedicated triggers for exactly this purpose - "Form Submitted" watches for a form's native submit event (or a configured equivalent), and "Click" watches for clicks matching a selector, including on elements added to the DOM after the page loaded (a "Click" rule with the right settings still catches dynamically injected buttons, unlike a plain document.querySelectorAll run once at load). Most "the rule doesn't fire" reports trace back to one of two things: the condition's selector is wrong or too narrow for the actual markup, or the form's own JavaScript intercepts the submit event (client-side validation, an AJAX submit, a framework's synthetic event system) in a way that changes what "submitted" even means for that specific form.

A second, quieter failure mode: the form successfully redirects the browser before an asynchronous tracking action (a Web SDK call, a network request) has time to complete - the same race condition that affects s.tl() link tracking, just triggered by form submission instead of a link click.

Fix it

1. Standard HTML form, no client-side validation blocking submit: a Core "Form Submitted" trigger scoped to the form's own selector is sufficient - no custom code required.

Launch rule condition - Core: Form Submitted
Selector: #contact-form
Elements Selector Matches CSS: #contact-form

2. Form validated or submitted via JavaScript (React/Vue form libraries, AJAX submission): the native submit event may never fire, or may fire before validation passes. Track it from application code via a data-layer push at the point validation actually succeeds, and trigger the Launch rule off a Custom Event instead of Core's native form trigger:

Application code - push only after validation passes
function onValidSubmit(formName) {
  window.digitalData = window.digitalData || [];
  window.digitalData.push({ event: 'formValidatedAndSubmitted', formName: formName });
  document.dispatchEvent(new CustomEvent('adobe:formSubmitted', { detail: { formName } }));
}

Then use a Core "Custom Event" trigger listening for adobe:formSubmitted on document, reading event.detail.formName in a data element.

3. Click tracking on dynamically added elements (a "Load More" button re-rendering a list, a modal injected after an API call): Launch's Click trigger delegates from the document by default in most configurations, so it still catches elements matching the selector even if they didn't exist at page load - confirm this is enabled in the rule's advanced settings rather than assuming it, since a delegated vs. direct-bind setting is a real, configurable difference that silently breaks tracking on re-rendered lists if set the narrower way.

4. If the form redirects immediately on submit and an async tracking call needs time to complete, delay the actual form submission the same way link tracking delays navigation - intercept the native submit, fire tracking, then submit programmatically after a short delay or once the beacon confirms:

Delay native submit until tracking has a chance to send
document.querySelector('#contact-form').addEventListener('submit', function (e) {
  e.preventDefault();
  var form = this;
  window.digitalData = window.digitalData || [];
  window.digitalData.push({ event: 'formSubmitted', formName: 'contact' });
  setTimeout(function () { form.submit(); }, 150);
});

Only reach for this pattern when the form's own submit causes a full navigation. A form submitted via AJAX that stays on the page doesn't need it - there's no unload race to guard against.

How to verify it worked

  • With the AEP Debugger open, submit the form (or click the tracked element) and confirm the rule fires exactly once, with the form-name or click-label data element resolved correctly - not blank, not stale from a previous action.
  • Test a failed validation path (submit with a required field empty) and confirm the event does NOT fire - a rule bound to the raw submit event rather than a "validation passed" signal will often fire on every attempt, including failed ones, silently inflating the metric.
  • For a redirecting form, confirm in the Network tab that the tracking beacon shows as completed before the navigation request starts - the same check used for link-tracking races.

Illustrative, not a measured result: a lead form tracked off the raw submit event might see its reported conversion count drop to a more accurate figure once tracking moves to fire only after client-side validation passes, excluding the failed-attempt submissions that were previously counted.

Webclat is not affiliated with Adobe Inc.