Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

HubSpot Form Abandonment Capture

Capture email addresses from users who start filling out HubSpot forms but abandon them before submitting. This solution automatically creates or updates HubSpot contacts with a tag indicating form abandonment.

Architecture

  • Client-Side Script: Lightweight JavaScript snippet that detects email input in HubSpot forms and sends data when forms are abandoned
  • Cloudflare Worker: Serverless endpoint that receives abandonment data and creates/updates HubSpot contacts via the HubSpot API

Prerequisites

  • A HubSpot account
  • A Cloudflare account (free tier works)
  • Node.js and npm installed locally
  • Access to your website's HTML to add the capture script

Setup Instructions

Step 1: HubSpot Configuration

1.1 Create a HubSpot Private App

  1. Log into your HubSpot account
  2. Navigate to SettingsIntegrationsPrivate Apps
  3. Click Create a private app
  4. Give it a name (e.g., "Form Abandonment Capture")
  5. Under Scopes, select:
    • crm.objects.contacts.write - Required to create/update contacts
  6. Click Create app
  7. Copy the Access Token - you'll need this for the Cloudflare Worker

1.2 Create Custom Contact Properties

You'll need to create custom properties to track form abandonment data:

  1. Navigate to SettingsPropertiesContact properties

  2. Click Create property

  3. Create the following properties:

    Property 1: Form Abandonment Status

    • Label: Form Abandonment Status
    • Internal name: form_abandonment_status
    • Type: Single-line text
    • Description: Status indicating form abandonment

    Property 2: Form Abandonment Page

    • Label: Form Abandonment Page
    • Internal name: form_abandonment_page
    • Type: Single-line text
    • Description: URL of the page where form was abandoned

    Property 3: Form Abandonment Form ID (Optional)

    • Label: Form Abandonment Form ID
    • Internal name: form_abandonment_form_id
    • Type: Single-line text
    • Description: HubSpot form ID that was abandoned

    Property 4: Form Abandonment Form Name (Optional)

    • Label: Form Abandonment Form Name
    • Internal name: form_abandonment_form_name
    • Type: Single-line text
    • Description: Name of the form that was abandoned

Step 2: Deploy Cloudflare Worker

2.1 Install Dependencies

cd worker
npm install

2.2 Configure Wrangler

If you haven't used Wrangler before, you'll need to authenticate:

npx wrangler login

2.3 Set HubSpot Token Secret

Set your HubSpot Private App token as a Cloudflare Worker secret:

npx wrangler secret put HUBSPOT_TOKEN

When prompted, paste your HubSpot Private App access token.

2.4 Deploy the Worker

npm run deploy

After deployment, Wrangler will display your Worker URL (e.g., https://hubspot-form-abandonment.your-subdomain.workers.dev). Save this URL - you'll need it for the next step.

Step 3: Configure Client Script

  1. Open snippet/capture.js
  2. Find the WORKER_URL constant near the top of the file
  3. Replace 'https://your-worker-name.your-subdomain.workers.dev' with your actual Worker URL from Step 2.4
const WORKER_URL = 'https://hubspot-form-abandonment.your-subdomain.workers.dev';

Step 4: Add Script to Your Website

Add the capture script to any page that contains HubSpot forms. You can do this in several ways:

Option A: Direct Script Tag (Recommended)

Add this before the closing </body> tag on your pages:

<script src="https://your-domain.com/path/to/capture.js"></script>

Or inline the script directly:

<script>
  // Paste the entire contents of snippet/capture.js here
</script>

Option B: Via Google Tag Manager

  1. Create a new Custom HTML tag
  2. Paste the contents of snippet/capture.js
  3. Set trigger to fire on all pages (or specific pages with forms)

Option C: Via HubSpot Tracking Code

If you're using HubSpot's tracking code, you can add the script there as well.

Important: The script must load after HubSpot's form script loads, or use the MutationObserver fallback (which is already included).

How It Works

  1. Email Detection: The script monitors HubSpot forms on the page and detects when an email address is entered
  2. Capture Triggers: Email is captured when:
    • User leaves the email field (blur event)
    • User types in the email field (debounced)
    • User navigates away from the page (beforeunload event)
  3. Submission Detection: If the form is successfully submitted, no abandonment data is sent
  4. Contact Creation: The Worker receives the email and creates/updates a HubSpot contact with:
    • The email address
    • form_abandonment_status set to "Started form - did not finish"
    • Additional metadata (page URL, form ID, form name)

Testing

Test Form Abandonment Capture

  1. Navigate to a page with a HubSpot form
  2. Enter a test email address in the form
  3. Do not submit the form
  4. Navigate away from the page or close the tab
  5. Check your HubSpot contacts - you should see a new contact (or updated contact) with:
    • The email address you entered
    • form_abandonment_status = "Started form - did not finish"
    • form_abandonment_page = URL of the page

Test Form Submission (Should Not Capture)

  1. Navigate to a page with a HubSpot form
  2. Enter a test email address
  3. Submit the form successfully
  4. Check HubSpot - the contact should be created through normal form submission, but should NOT have the abandonment status

Debugging

Open your browser's developer console. You should see log messages like:

[Form Abandonment] Initialized
[Form Abandonment] Listeners attached to form
[Form Abandonment] Email captured: test@example.com

If you see errors, check:

  • Worker URL is correct in capture.js
  • HubSpot token is set correctly in Cloudflare Worker secrets
  • Custom properties exist in HubSpot with correct internal names
  • Private App has the correct scopes

Worker API

The Worker accepts POST requests with the following JSON payload:

{
  "email": "user@example.com",
  "formId": "optional-form-id",
  "formName": "Optional Form Name",
  "pageUrl": "https://example.com/page"
}

Response (200 OK):

{
  "success": true,
  "message": "Contact created/updated"
}

Error Response (400 Bad Request):

{
  "error": "Invalid or missing email address"
}

Customization

Change Abandonment Status Text

Edit worker/src/index.ts and change the form_abandonment_status value:

form_abandonment_status: 'Your custom status text',

Adjust Capture Delay

In snippet/capture.js, modify the EMAIL_CAPTURE_DELAY constant:

const EMAIL_CAPTURE_DELAY = 2000; // milliseconds

Add Additional Data

To capture additional form fields or metadata, modify:

  1. The payload structure in snippet/capture.js
  2. The AbandonmentData interface in worker/src/index.ts
  3. The contact properties mapping in the Worker

Troubleshooting

Contacts Not Being Created

  1. Check Worker Logs: Use wrangler tail to see real-time logs
  2. Verify Token: Ensure HUBSPOT_TOKEN secret is set correctly
  3. Check Scopes: Verify Private App has crm.objects.contacts.write scope
  4. Property Names: Ensure custom property internal names match exactly (case-sensitive)

Script Not Detecting Forms

  1. Check Console: Look for initialization messages
  2. Form Loading: Ensure HubSpot forms load before the script (or use MutationObserver fallback)
  3. Form Selectors: Verify your HubSpot forms use standard HubSpot form structure

Duplicate Contacts

The Worker uses HubSpot's upsert functionality (create or update by email). If you're seeing duplicates:

  • Check if email addresses have different casing (HubSpot may treat them as different)
  • Verify the email field is being used as the unique identifier

Security Considerations

  • The Worker URL is public (it's in client-side JavaScript)
  • The Worker validates email format before sending to HubSpot
  • Consider adding rate limiting or IP-based restrictions if needed
  • The HubSpot token is stored securely as a Cloudflare Worker secret

Cost

  • Cloudflare Workers: Free tier includes 100,000 requests/day
  • HubSpot API: Free tier includes 100 API calls/10 seconds
  • For high-traffic sites, monitor usage and upgrade plans as needed

Support

For issues or questions:

  1. Check Cloudflare Worker logs: wrangler tail
  2. Check browser console for client-side errors
  3. Verify HubSpot API limits and quotas

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages