Let me provide a complete solution that addresses event delegation, AJAX form submission, and script load order issues.
First, use HubSpot’s proper form callback system to ensure your code runs at the right time:
window.addEventListener('message', event => {
if (event.data.type === 'hsFormCallback') {
if (event.data.eventName === 'onFormSubmit') {
handleFormSubmission(event.data);
}
}
});
For the AJAX enrichment, never prevent the default submission. Instead, send your enrichment data in parallel:
function handleFormSubmission(formData) {
const enrichmentData = prepareEnrichmentData(formData);
fetch('/api/enrich-contact', {
method: 'POST',
body: JSON.stringify(enrichmentData)
}).catch(err => console.error('Enrichment failed:', err));
}
Notice we’re using .catch() but not blocking the form. The form submission completes normally, triggering your workflow, while enrichment happens asynchronously. If enrichment fails, the workflow still fires.
For script load order, inline critical initialization code directly in your HubSpot form embed:
<script>
(function() {
if (typeof window.hsFormCallbacks === 'undefined') {
window.hsFormCallbacks = [];
}
window.hsFormCallbacks.push(handleFormSubmission);
})();
</script>
This ensures the callback is registered before the form loads, eliminating timing issues.
The key insight here is separation of concerns: let HubSpot handle form submission and workflow triggering normally, while your custom code runs as a non-blocking enhancement. This architecture prevents the 30% failure rate you’re experiencing because the critical path (form submit → workflow trigger) never depends on your custom code succeeding.
For event delegation specifically, avoid direct element selectors. Use the form callback system which provides you with form data regardless of DOM structure. This makes your code resilient to HubSpot’s form rendering changes.
Implement error logging in your enrichment function so you can track when and why it fails without impacting the main workflow. This gives you visibility into the 30% failure cases while ensuring they don’t break the user experience.