Meta Pixel Event Tracking on HubSpot | Blue Frog Docs

Meta Pixel Event Tracking on HubSpot

Track HubSpot forms, CTAs, meetings, and custom events with Meta Pixel for Facebook and Instagram advertising.

Meta Pixel Event Tracking on HubSpot

Beyond basic PageView tracking, Meta Pixel can track HubSpot-specific events like form submissions, CTA clicks, and meeting bookings to optimize your Facebook and Instagram ad campaigns.

Prerequisites

  1. Install Meta Pixel on HubSpot
  2. Verify base pixel is working (PageView events firing)
  3. Access to HubSpot Site Header HTML or GTM

Meta Pixel Standard Events

Event When to Fire HubSpot Use Case
Lead Form submitted Contact form, demo request
CompleteRegistration User signs up Email subscription, account creation
Contact Meeting booked HubSpot meetings tool
Schedule Calendar event Meeting scheduled
ViewContent Page/content viewed Blog posts, resources
Purchase Transaction completed HubSpot Payments/Commerce
AddToCart Item added to cart Payment link clicked

Tracking HubSpot Form Submissions

Method 1: Form Event Listener (All Forms)

Track all HubSpot form submissions as "Lead" events.

Add to Site Header HTML after Meta Pixel base code:

<script>
  // Track all HubSpot form submissions
  window.addEventListener('message', function(event) {
    if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
      var formId = event.data.id;

      // Fire Meta Pixel Lead event
      fbq('track', 'Lead', {
        content_name: 'Form Submission',
        content_category: 'contact_form',
        form_id: formId,
        {% if contact %}
        lifecycle_stage: '{{ contact.lifecycle_stage }}',
        {% endif %}
        source: 'hubspot'
      });

      console.log('Meta Pixel: Lead event tracked for form', formId);
    }
  });
</script>

Method 2: Specific Forms with Different Events

Track different forms with different events or values:

<script>
  window.addEventListener('message', function(event) {
    if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
      var formId = event.data.id;

      // Contact form
      if (formId === 'your-contact-form-guid') {
        fbq('track', 'Contact', {
          content_name: 'Contact Form',
          value: 10.00,
          currency: 'USD'
        });
      }

      // Demo request form
      else if (formId === 'your-demo-form-guid') {
        fbq('track', 'Lead', {
          content_name: 'Demo Request',
          content_category: 'high_intent',
          value: 50.00,
          currency: 'USD'
        });
      }

      // Newsletter signup
      else if (formId === 'your-newsletter-guid') {
        fbq('track', 'CompleteRegistration', {
          content_name: 'Newsletter Signup',
          status: 'subscribed'
        });
      }

      // Default: track as generic lead
      else {
        fbq('track', 'Lead', {
          form_id: formId
        });
      }
    }
  });
</script>

Method 3: GTM Implementation

If using Google Tag Manager:

1. Add Data Layer Push to Site Header HTML:

<script>
  window.addEventListener('message', function(event) {
    if (event.data.type === 'hsFormCallback' && event.data.eventName === 'onFormSubmitted') {
      dataLayer.push({
        'event': 'form_submission',
        'formId': event.data.id,
        'formType': 'hubspot'
      });
    }
  });
</script>

2. Create Custom HTML Tag in GTM:

  • Tag Type: Custom HTML
  • HTML:
    <script>
      fbq('track', 'Lead', {
        'form_id': '{{DL - formId}}',
        'source': 'hubspot'
      });
    </script>
    
  • Trigger: Custom Event form_submission

Tracking HubSpot CTA Clicks

Track when visitors click HubSpot CTAs.

CTA Click Event Listener

<script>
  document.addEventListener('click', function(event) {
    // Check if clicked element is a HubSpot CTA
    var ctaElement = event.target.closest('.cta_button, [class*="hs-cta"]');

    if (ctaElement) {
      var ctaId = ctaElement.getAttribute('data-hs-cta-id') || 'unknown';
      var ctaText = ctaElement.textContent.trim();
      var ctaUrl = ctaElement.href || '';

      // Track as custom event
      fbq('trackCustom', 'CTAClick', {
        'cta_id': ctaId,
        'cta_text': ctaText,
        'cta_url': ctaUrl,
        'page_url': window.location.href
      });

      console.log('Meta Pixel: CTA click tracked:', ctaText);
    }
  });
</script>

Track Smart CTA Variants

For personalized Smart CTAs:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    var smartCtas = document.querySelectorAll('[class*="hs-cta"][data-hs-cta-variant]');

    smartCtas.forEach(function(cta) {
      cta.addEventListener('click', function() {
        var variant = cta.getAttribute('data-hs-cta-variant');

        fbq('trackCustom', 'SmartCTAClick', {
          'cta_variant': variant,
          'cta_id': cta.getAttribute('data-hs-cta-id'),
          {% if contact %}
          'lifecycle_stage': '{{ contact.lifecycle_stage }}',
          {% endif %}
        });
      });
    });
  });
</script>

Tracking Meeting Bookings

Track HubSpot meeting bookings as high-value conversions.

Meeting Booking Event

<script>
  // Listen for meeting bookings
  window.addEventListener('message', function(event) {
    if (event.data.meetingBookSucceeded === true) {
      var meetingData = event.data.meetingPayload || {};

      // Track as Schedule event (standard)
      fbq('track', 'Schedule', {
        content_name: 'Meeting Booked',
        meeting_type: meetingData.meetingType || 'unknown',
        value: 100.00, // Assign value to meetings
        currency: 'USD',
        {% if contact %}
        lifecycle_stage: '{{ contact.lifecycle_stage }}',
        {% endif %}
      });

      // Also track as custom Contact event
      fbq('track', 'Contact', {
        content_name: 'Meeting Scheduled',
        value: 100.00,
        currency: 'USD'
      });

      console.log('Meta Pixel: Meeting booking tracked');
    }
  });
</script>

Track Meeting Widget Interactions

Track when meeting widget is opened:

<script>
  window.addEventListener('message', function(event) {
    if (event.data.type === 'MEETINGS_OPENED') {
      fbq('trackCustom', 'MeetingWidgetOpened', {
        'page_url': window.location.href
      });
    }

    if (event.data.type === 'MEETINGS_TIME_SELECTED') {
      fbq('trackCustom', 'MeetingTimeSelected');
    }
  });
</script>

Tracking HubSpot Chat Interactions

Track live chat interactions.

Chat Event Tracking

<script>
  // Wait for HubSpot conversations to load
  window.hsConversationsOnReady = [function() {
    window.HubSpotConversations.on('conversationStarted', function() {
      fbq('trackCustom', 'ChatStarted', {
        'chat_type': 'live_chat',
        'source': 'hubspot'
      });
    });

    window.HubSpotConversations.on('conversationClosed', function() {
      fbq('trackCustom', 'ChatCompleted', {
        'chat_type': 'live_chat'
      });
    });
  }];
</script>

Tracking Content Views

Blog Post Views

Track blog post views with metadata:

{% if content.type == 'blog_post' %}
<script>
  fbq('track', 'ViewContent', {
    'content_name': '{{ content.name }}',
    'content_type': 'blog_post',
    'content_ids': ['{{ content.id }}'],
    'content_category': '{{ content.category_id }}',
    'author': '{{ content.blog_post_author.display_name }}'
  });
</script>
{% endif %}

Resource Downloads

Track file/resource downloads:

<script>
  document.addEventListener('click', function(event) {
    var link = event.target.closest('a');

    if (link && link.href && /\.(pdf|docx?|xlsx?|pptx?|zip)$/i.test(link.href)) {
      var fileName = link.href.split('/').pop();

      fbq('track', 'ViewContent', {
        'content_name': fileName,
        'content_type': 'resource',
        'content_category': 'download'
      });

      console.log('Meta Pixel: Download tracked:', fileName);
    }
  });
</script>

Tracking Ecommerce Events

Product Views

For HubSpot Commerce or product pages:

{% if content.product_id %}
<script>
  fbq('track', 'ViewContent', {
    'content_name': '{{ content.product_name }}',
    'content_ids': ['{{ content.product_id }}'],
    'content_type': 'product',
    'value': {{ content.product_price }},
    'currency': 'USD'
  });
</script>
{% endif %}

Add to Cart

Track payment link clicks:

<script>
  document.addEventListener('click', function(event) {
    var paymentLink = event.target.closest('a[href*="payments.hubspot.com"], .hs-payment-link');

    if (paymentLink) {
      var productName = paymentLink.getAttribute('data-product-name') || 'Product';
      var productPrice = paymentLink.getAttribute('data-product-price') || '0';

      fbq('track', 'AddToCart', {
        'content_name': productName,
        'value': parseFloat(productPrice),
        'currency': 'USD'
      });
    }
  });
</script>

Purchase Conversion

On payment confirmation page:

{% if content.payment_confirmed %}
<script>
  fbq('track', 'Purchase', {
    'value': {{ payment.amount }},
    'currency': '{{ payment.currency }}',
    'content_name': '{{ payment.product_name }}',
    'content_ids': ['{{ payment.product_id }}'],
    'content_type': 'product'
  });
</script>
{% endif %}

Custom Events for HubSpot Workflows

Track when contacts move through lifecycle stages:

{% if contact.lifecycle_stage == 'marketingqualifiedlead' and contact.lifecyclestage_lastupdated %}
<script>
  fbq('trackCustom', 'BecameMQL', {
    'lifecycle_stage': 'mql',
    'source': 'hubspot_workflow'
  });
</script>
{% endif %}

Conversions API (Server-Side Tracking)

For more reliable tracking, use Meta Conversions API alongside Meta Pixel.

Why Use Conversions API?

  • Bypasses ad blockers - Server-side events can't be blocked
  • Better data accuracy - Not affected by browser settings
  • iOS 14.5+ privacy - Tracks iOS users more reliably
  • Duplicate event handling - Meta automatically deduplicates

Implementation via HubSpot Workflows

  1. Create Workflow triggered by form submission

  2. Add Webhook Action with Conversions API endpoint:

    • URL: https://graph.facebook.com/v18.0/YOUR_PIXEL_ID/events
    • Method: POST
    • Headers:
      • Content-Type: application/json
  3. Payload:

{
  "data": [{
    "event_name": "Lead",
    "event_time": {{ "now" | unixtimestamp }},
    "action_source": "website",
    "user_data": {
      "em": "{{ contact.email | sha256 }}",
      "fn": "{{ contact.firstname | sha256 }}",
      "ln": "{{ contact.lastname | sha256 }}",
      "ct": "{{ contact.city | sha256 }}",
      "st": "{{ contact.state | sha256 }}",
      "zp": "{{ contact.zip | sha256 }}",
      "country": "{{ contact.country | sha256 }}"
    },
    "custom_data": {
      "form_id": "{{ form.guid }}",
      "lifecycle_stage": "{{ contact.lifecycle_stage }}"
    },
    "event_source_url": "{{ page.url }}"
  }],
  "access_token": "YOUR_CONVERSIONS_API_ACCESS_TOKEN"
}

Note: User data must be hashed using SHA-256.

See Meta Conversions API documentation for details.

Testing Meta Pixel Events

1. Use Meta Pixel Helper Extension

  • Install Meta Pixel Helper for Chrome
  • Visit your HubSpot site
  • Trigger events (submit form, click CTA, etc.)
  • Extension shows events fired in real-time

2. Use Meta Events Manager Test Events

  1. Go to Events Manager → Select Pixel
  2. Click Test Events tab
  3. Enter your website URL
  4. Open Website
  5. Trigger events
  6. See events appear in Test Events within seconds

3. Check Browser Console

// View fired events
console.log(fbq.queue); // Recent events

4. Verify Event Parameters

In Meta Events Manager:

  • Click on event in Test Events
  • Expand to see parameters
  • Verify all custom parameters passed correctly

Troubleshooting

Events Not Firing

Check:

  1. Meta Pixel base code is installed
  2. Event code comes after base code
  3. No JavaScript errors in console
  4. Event syntax is correct

Debug:

// Test manual event firing
fbq('track', 'Lead', {'test': 'manual_fire'});

Events Firing Multiple Times

Cause: Event listener triggers multiple times

Fix: Use event flag:

var formSubmitted = false;
window.addEventListener('message', function(event) {
  if (event.data.type === 'hsFormCallback' && !formSubmitted) {
    formSubmitted = true;
    fbq('track', 'Lead');
  }
});

Parameters Not Passing

Issue: Custom parameters empty or undefined

Debug:

console.log('Form ID:', event.data.id);
console.log('Contact Email:', '{{ contact.email }}');

Events Not Showing in Ads Manager

Delay: Events can take 15-30 minutes to appear in Ads Manager (but immediate in Test Events).

Solution: Use Test Events for immediate verification.

Event Optimization for Ad Campaigns

Assign Values to Events

Help Meta optimize for valuable actions:

fbq('track', 'Lead', {
  'value': 25.00, // Estimated lead value
  'currency': 'USD',
  'predicted_ltv': 500.00 // Lifetime value estimate
});

Use Custom Conversions

In Meta Ads Manager:

  1. Create Custom Conversion based on URL or event
  2. Use for campaign optimization
  3. Track specific HubSpot landing pages or forms

Segment Events by Lifecycle Stage

fbq('track', 'Lead', {
  'lifecycle_stage': '{{ contact.lifecycle_stage }}',
  'lead_quality': '{% if contact.lifecycle_stage == "marketingqualifiedlead" %}high{% else %}medium{% endif %}'
});

Next Steps

For general Meta Pixel concepts, see Meta Pixel Guide.

// SYS.FOOTER