Skip to main content

B2B Lead Generation Analytics

Comprehensive analytics setup for B2B lead generation, including form tracking, lead scoring, and offline conversion imports.

B2B Analytics Challenges

Unique Characteristics

| B2B Challenge | Analytics Implication | |---------------|----------------------| | Long sales cycles | Extended attribution windows | | Multiple stakeholders | Account-level tracking needed | | Offline conversions | CRM integration required | | High-value deals | Lead quality > quantity | | Complex funnels | Multi-touch attribution |

The B2B Funnel

┌─────────────────────────────────────────────────────────┐
│                    B2B Lead Funnel                       │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Website    →   Lead    →    MQL     →    SQL    →  Won │
│  Visitor        Gen          Qualified    Sales      Deal│
│                                                         │
│  Tracked in:                                            │
│  GA4           GA4/CRM       CRM          CRM       CRM │
│                    │          │            │         │  │
│                    └──────────┴────────────┴─────────┘  │
│                        Import back to Google Ads        │
│                                                         │
└─────────────────────────────────────────────────────────┘

Form Tracking

Standard Form Events

// Form viewed
dataLayer.push({
  event: 'form_view',
  form_name: 'contact_sales',
  form_location: 'pricing_page',
  form_type: 'lead_gen'
});

// Form started (first interaction)
dataLayer.push({
  event: 'form_start',
  form_name: 'contact_sales',
  form_location: 'pricing_page'
});

// Form submitted
dataLayer.push({
  event: 'generate_lead',
  form_name: 'contact_sales',
  form_location: 'pricing_page',
  lead_type: 'sales_inquiry',
  company_size: '51-200',
  industry: 'technology',
  value: 500  // Estimated lead value
});

Field-Level Tracking

Track form abandonment by monitoring field completion:

// Track field completion
function trackFieldComplete(formName, fieldName) {
  dataLayer.push({
    event: 'form_field_complete',
    form_name: formName,
    field_name: fieldName,
    field_order: getFieldOrder(fieldName)
  });
}

// Attach to form fields
document.querySelectorAll('#contact-form input').forEach(input => {
  input.addEventListener('blur', function() {
    if (this.value) {
      trackFieldComplete('contact_sales', this.name);
    }
  });
});

Lead Quality Signals

Capture data that indicates lead quality:

dataLayer.push({
  event: 'generate_lead',
  form_name: 'demo_request',
  // Standard info
  lead_type: 'demo_request',

  // Quality signals
  company_size: '201-500',
  industry: 'financial_services',
  job_title_category: 'executive',  // C-level, VP, Director, Manager, IC
  use_case: 'enterprise_deployment',
  budget_range: '100k_plus',
  timeline: 'this_quarter',

  // Lead scoring input
  lead_score: calculateLeadScore(),
  lead_grade: 'A'  // Based on company fit
});

Lead Scoring

Scoring Framework

function calculateLeadScore() {
  let score = 0;

  // Behavioral scoring
  score += pageviews > 5 ? 10 : pageviews * 2;
  score += visitedPricing ? 15 : 0;
  score += visitedCaseStudies ? 10 : 0;
  score += downloadedContent ? 20 : 0;
  score += watchedDemo ? 25 : 0;

  // Form-based scoring
  score += getCompanySizeScore(companySize);
  score += getIndustryScore(industry);
  score += getTitleScore(jobTitle);
  score += getTimelineScore(timeline);

  return score;
}

function getCompanySizeScore(size) {
  const scores = {
    '1-10': 5,
    '11-50': 10,
    '51-200': 15,
    '201-500': 25,
    '501-1000': 30,
    '1000+': 35
  };
  return scores[size] || 0;
}

Pass Score to GA4

// Include score with lead event
dataLayer.push({
  event: 'generate_lead',
  lead_score: 75,
  lead_grade: 'A',
  // ... other params
});

// Also set as user property for future analysis
dataLayer.push({
  event: 'set_user_properties',
  user_properties: {
    lead_score: 75,
    lead_grade: 'A',
    lead_status: 'new'
  }
});

Content Engagement

Content Asset Tracking

// Content download
dataLayer.push({
  event: 'file_download',
  file_name: 'enterprise-security-guide.pdf',
  content_type: 'whitepaper',
  content_topic: 'security',
  content_stage: 'consideration'  // awareness, consideration, decision
});

// Webinar registration
dataLayer.push({
  event: 'webinar_registration',
  webinar_name: 'Data Strategy 2024',
  webinar_topic: 'analytics',
  webinar_date: '2024-02-15'
});

// Video engagement
dataLayer.push({
  event: 'video_complete',
  video_title: 'Product Demo',
  video_duration: 420,
  video_type: 'product_demo'
});

Engagement Scoring

// Track engagement depth
const engagementScore = {
  pageviews: 0,
  downloads: 0,
  videoWatched: 0,
  minutesOnSite: 0
};

// Update on events
dataLayer.push = (function(original) {
  return function(data) {
    if (data.event === 'page_view') engagementScore.pageviews++;
    if (data.event === 'file_download') engagementScore.downloads++;
    if (data.event === 'video_complete') engagementScore.videoWatched++;

    // Send engagement tier
    if (shouldUpdateTier()) {
      original.call(this, {
        event: 'engagement_tier_change',
        engagement_tier: calculateTier(engagementScore)
      });
    }

    return original.apply(this, arguments);
  };
})(dataLayer.push);

Offline Conversion Import

Why Import Offline Conversions?

Ad Click → Lead → MQL → SQL → Opportunity → Closed Won
   │        │                                    │
   │        └─── Tracked in GA4 ────────────────┘
   │                                             │
   └──── Click ID (gclid) links them ───────────┘

Google Ads Offline Import

  1. Capture GCLID at form submission:
// Get GCLID from URL or cookie
function getGclid() {
  // Check URL first
  const urlParams = new URLSearchParams(window.location.search);
  let gclid = urlParams.get('gclid');

  // Fall back to cookie
  if (!gclid) {
    const cookies = document.cookie.split(';');
    for (let cookie of cookies) {
      if (cookie.trim().startsWith('_gcl_aw=')) {
        gclid = cookie.split('.').pop();
        break;
      }
    }
  }
  return gclid;
}

// Include in form submission
dataLayer.push({
  event: 'generate_lead',
  gclid: getGclid(),
  lead_id: generatedLeadId,
  // ... other params
});
  1. Store in CRM with lead record

  2. Import conversions when status changes:

# Google Ads offline conversion format
Parameters:TimeZone=America/Los_Angeles
Google Click ID,Conversion Name,Conversion Time,Conversion Value,Conversion Currency
abc123,SQL,2024-01-15 14:30:00,1000,USD
def456,Closed Won,2024-01-20 09:15:00,50000,USD

GA4 Offline Events (Measurement Protocol)

// Server-side: Import CRM events to GA4
const ga4Event = {
  client_id: 'stored_client_id',  // Captured at lead time
  user_id: 'lead_123',
  events: [{
    name: 'crm_stage_change',
    params: {
      stage: 'sql',
      lead_id: 'lead_123',
      opportunity_value: 50000,
      days_since_lead: 14
    }
  }]
};

// Send via Measurement Protocol
fetch(`https://www.google-analytics.com/mp/collect?measurement_id=${GA4_ID}&api_secret=${SECRET}`, {
  method: 'POST',
  body: JSON.stringify(ga4Event)
});

Account-Based Tracking

Company Identification

// If using Clearbit, 6sense, or similar
if (window.clearbit) {
  clearbit.reveal(function(error, company) {
    if (company) {
      dataLayer.push({
        event: 'company_identified',
        company_name: company.name,
        company_domain: company.domain,
        company_industry: company.category.industry,
        company_size: company.metrics.employees,
        company_revenue: company.metrics.estimatedAnnualRevenue
      });
    }
  });
}

Account-Level Events

// Track at account level
dataLayer.push({
  event: 'page_view',
  // Standard page view params...

  // Account-level dimensions
  account_id: identifiedCompanyId || 'anonymous',
  account_name: companyName || 'unknown',
  account_tier: getAccountTier(companyRevenue),
  is_target_account: isInTargetList(companyDomain)
});

CRM Integration

HubSpot Integration

// Push GA4 client_id to HubSpot
if (window._hsq) {
  _hsq.push(['identify', {
    ga_client_id: getGA4ClientId()
  }]);
}

// Track HubSpot form submissions in GA4
hbspt.forms.create({
  // ... form config
  onFormSubmit: function($form) {
    dataLayer.push({
      event: 'generate_lead',
      form_name: 'hubspot_contact',
      form_id: formId
    });
  }
});

Salesforce Integration

Sync key fields for attribution:

| GA4 Data | Salesforce Field | |----------|------------------| | client_id | GA4_Client_ID__c | | gclid | GCLID__c | | source | Lead_Source_Detail__c | | medium | Lead_Medium__c | | campaign | Lead_Campaign__c |

Attribution for B2B

Extended Windows

Configure for longer B2B cycles:

// Set extended attribution in GA4 Admin
// Admin → Attribution Settings → Lookback window: 90 days

Multi-Touch Analysis

-- BigQuery: Touchpoint analysis
WITH touchpoints AS (
  SELECT
    user_pseudo_id,
    traffic_source.source,
    traffic_source.medium,
    traffic_source.campaign,
    event_timestamp,
    ROW_NUMBER() OVER (PARTITION BY user_pseudo_id ORDER BY event_timestamp) as touch_order
  FROM `project.analytics.events_*`
  WHERE event_name = 'page_view'
    AND traffic_source.source IS NOT NULL
),
conversions AS (
  SELECT
    user_pseudo_id,
    MIN(event_timestamp) as conversion_time
  FROM `project.analytics.events_*`
  WHERE event_name = 'generate_lead'
  GROUP BY 1
)
SELECT
  t.source,
  t.medium,
  t.touch_order,
  COUNT(*) as touchpoints,
  COUNT(DISTINCT c.user_pseudo_id) as conversions
FROM touchpoints t
LEFT JOIN conversions c ON t.user_pseudo_id = c.user_pseudo_id
  AND t.event_timestamp < c.conversion_time
GROUP BY 1, 2, 3
ORDER BY touch_order, conversions DESC

Reporting Dashboards

B2B Lead Dashboard

| Section | Metrics | |---------|---------| | Lead Volume | Total leads, by source, by form | | Lead Quality | Score distribution, by grade | | Conversion Funnel | Stage conversion rates | | Content Performance | Downloads, engagement by asset | | Pipeline Attribution | Opportunity value by source |

Sales & Marketing Alignment

| Marketing View | Sales View | |----------------|------------| | MQLs generated | SQLs accepted | | Cost per lead | Cost per opportunity | | Lead score accuracy | Win rate by lead score | | Content influence | Deal acceleration |


Previous: SaaS Analytics Next: E-commerce Analytics