Crazy Egg: Heatmaps, Session Recordings, | OpsBlu Docs

Crazy Egg: Heatmaps, Session Recordings,

Implement Crazy Egg heatmaps, scroll maps, session recordings, and A/B tests with the CE2 JavaScript API for visual UX optimization and conversion rate...

How Crazy Egg Works

Crazy Egg is a visual analytics platform that captures how visitors interact with your pages through heatmaps, scroll maps, click maps, session recordings, and built-in A/B testing. Instead of telling you that 73% of visitors left your page, Crazy Egg shows you that they all clicked a static image expecting it to be a button.

The data collection model is snapshot-based. You create a "snapshot" for a specific URL (or URL pattern), and Crazy Egg begins recording visitor interactions on that page. The JavaScript SDK captures mouse coordinates, click positions, scroll depth, viewport dimensions, and DOM state. This data is processed server-side into visual overlays: heatmaps that show click density, scroll maps that show how far visitors travel, and confetti views that segment clicks by referrer, device, or custom variables.

Session recordings work differently from snapshots. Once enabled, Crazy Egg records full visitor sessions across pages by capturing DOM mutations, scroll events, mouse movements, and click actions. These recordings are stored as lightweight event streams (not video), which keeps the file size small and allows playback at variable speed.

The A/B testing engine uses the same JavaScript SDK. When a test is active, Crazy Egg intercepts the page render, applies the variant modifications to the DOM, and tracks which variant each visitor sees. Conversions are measured against goals you define: clicks on a specific element, visits to a URL, or form submissions.

Installing the Crazy Egg Script

Add the Crazy Egg tracking script before the closing </head> tag. Your account number is in the script URL provided in your Crazy Egg dashboard under Tracking Code.

<script type="text/javascript" src="//script.crazyegg.com/pages/scripts/XXXX/XXXX.js" async="async"></script>

The XXXX/XXXX path is your unique account identifier. The script is approximately 20 KB and loads asynchronously, so it does not block page rendering.

Loading via Google Tag Manager

Create a Custom HTML tag in GTM with the following code. Set it to fire on All Pages.

<script type="text/javascript">
  (function () {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = '//script.crazyegg.com/pages/scripts/XXXX/XXXX.js';
    var entry = document.getElementsByTagName('script')[0];
    entry.parentNode.insertBefore(script, entry);
  })();
</script>

Verifying Installation

Open your site in Chrome, then open DevTools (F12) and go to the Network tab. Filter by crazyegg. You should see the script loading successfully (200 status). You can also type CE2 in the console. If it returns an object, the SDK is loaded.

In the Crazy Egg dashboard, navigate to Snapshots and check that your page's snapshot shows "Collecting Data." New snapshots typically begin receiving data within 5 minutes of installation.

Core Visual Analytics

Heatmaps

Heatmaps aggregate click data across all visitors into a color-coded overlay. Red indicates high click density, blue indicates low. Crazy Egg generates heatmaps automatically for any page with an active snapshot.

To control which pages get tracked, you can configure snapshots by exact URL, URL pattern with wildcards, or regex:

  • Exact: https://example.com/pricing
  • Wildcard: https://example.com/blog/*
  • Regex: https://example\.com/products/[0-9]+

Scroll Maps

Scroll maps show what percentage of visitors reached each vertical position on the page. A sharp drop-off at a specific point tells you that most visitors never see content below that line.

Crazy Egg measures scroll depth in percentage increments. The data powers a gradient overlay on your page: bright colors at the top (100% of visitors see this), fading to dark at the bottom. The exact percentages are shown in the sidebar.

Confetti Reports

Confetti view shows individual clicks as colored dots, each representing a single click. The color coding segments clicks by a dimension you choose:

  • Referral source (Google, Facebook, Direct)
  • Search term
  • New vs. returning visitor
  • Device type (desktop, tablet, mobile)
  • Operating system
  • Browser
  • Day of week
  • Time of day

This granularity reveals behavioral differences between segments. For example, mobile visitors might click a hamburger menu icon that desktop visitors ignore entirely.

Session Recordings

Recordings capture the full visitor experience. You can watch mouse movement, clicks, scrolling, typing (with sensitive fields masked), page transitions, and rage clicks (rapid repeated clicks on the same area).

Filter recordings by:

Page URL, date range, duration, country, device type,
referrer, new vs. returning, and custom user data

Crazy Egg automatically tags recordings that contain rage clicks, dead clicks (clicks on non-interactive elements), or error events.

Custom Event Tracking and User Data

Setting User Variables

Use the CE2 object to pass custom data that appears in confetti reports and recording filters:

// Set custom variables (up to 5)
CE2.set(1, 'Premium');         // Variable 1: Plan type
CE2.set(2, 'jane@acme.com');   // Variable 2: User email
CE2.set(3, 'Enterprise');      // Variable 3: Segment
CE2.set(4, '2025-06-15');      // Variable 4: Signup date
CE2.set(5, 'Onboarding');      // Variable 5: Lifecycle stage

Variables must be set after the Crazy Egg script loads. To safely handle the timing, wrap calls in a check:

function setCrazyEggVars() {
  if (typeof CE2 !== 'undefined') {
    CE2.set(1, currentUser.plan);
    CE2.set(2, currentUser.email);
  } else {
    setTimeout(setCrazyEggVars, 500);
  }
}
setCrazyEggVars();

Tracking Virtual Pageviews in SPAs

For single-page applications where URL changes do not trigger full page reloads, notify Crazy Egg of navigation events:

// After a client-side route change
if (typeof CE2 !== 'undefined') {
  CE2.virtualPageview();
}

In React with React Router:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function useCrazyEggTracking() {
  const location = useLocation();

  useEffect(() => {
    if (typeof CE2 !== 'undefined' && typeof CE2.virtualPageview === 'function') {
      CE2.virtualPageview();
    }
  }, [location.pathname]);
}

A/B Testing

Crazy Egg includes a visual A/B testing editor. You select an element on the page, modify it (change text, color, position, visibility), and Crazy Egg serves the modified version to a percentage of visitors.

Programmatic Variant Assignment

For more complex tests that require code changes, use the Crazy Egg Goals API to track conversions:

// Track a conversion goal (e.g., form submission)
if (typeof CE2 !== 'undefined') {
  CE2.goal('signup_form_completed');
}

Setting Up a Test

  1. Create a new A/B test in the Crazy Egg dashboard
  2. Select the page URL to test
  3. Use the visual editor to create one or more variants
  4. Set traffic allocation (e.g., 50/50 split)
  5. Define the conversion goal (click on element, page visit, or custom goal)
  6. Launch the test and wait for statistical significance

Crazy Egg calculates statistical significance automatically and marks the winning variant when confidence reaches 95%.

Integration with Other Tools

Forwarding Crazy Egg Insights to GA4

Crazy Egg does not send data to GA4 directly. However, you can use the user variable data to create custom dimensions in GA4 that correspond to Crazy Egg segments:

// Set matching dimensions in both platforms
CE2.set(1, userSegment);

gtag('set', 'user_properties', {
  ce_segment: userSegment
});

Using Crazy Egg with GTM Data Layer

Pass data layer values into Crazy Egg variables for consistent segmentation:

window.dataLayer = window.dataLayer || [];

// Listen for data layer events and forward to Crazy Egg
(function() {
  var originalPush = window.dataLayer.push;
  window.dataLayer.push = function() {
    var result = originalPush.apply(this, arguments);
    var data = arguments[0];
    if (data && data.event === 'user_identified' && typeof CE2 !== 'undefined') {
      CE2.set(1, data.user_type);
      CE2.set(2, data.user_plan);
    }
    return result;
  };
})();

Exporting Data

Crazy Egg provides CSV exports for heatmap click data and recording metadata. Use these exports to correlate Crazy Egg findings with conversion data from your analytics platform. The export includes click coordinates, element selectors, timestamps, and the visitor's segment data.

Common Errors

Error Cause Fix
Heatmap shows no data after 24 hours Snapshot URL does not match the actual page URL (www vs. non-www, HTTP vs. HTTPS) Edit the snapshot and update the URL to match exactly, including protocol and subdomain
CE2 is not defined Script has not finished loading, or was blocked by ad blocker or CSP Wrap CE2 calls in a typeof check; add script.crazyegg.com to CSP script-src
Recordings show blank white page CSS/font resources blocked by CORS or CSP on the recording server Ensure Access-Control-Allow-Origin headers allow Crazy Egg's recording domain
A/B test shows flicker (original content flashes before variant loads) Crazy Egg script loads after the browser paints the original content Move the Crazy Egg script higher in <head> or add a CSS rule to hide the tested element until the script runs
Scroll map cuts off mid-page Page uses lazy loading that does not render content until scroll Ensure lazy-loaded content is present in the DOM (even if hidden) when the page loads
Heatmap clicks appear offset from elements Page layout shifted after Crazy Egg captured the snapshot screenshot Retake the snapshot to capture the current layout
Variables not appearing in confetti CE2.set() called before the SDK finished loading Use the polling pattern with setTimeout to wait for CE2 to be defined
Recording does not capture iframe content Crazy Egg cannot record cross-origin iframes Host iframe content on the same domain, or accept that iframe interactions will not appear in recordings
Mobile heatmap is empty Snapshot only tracks the desktop viewport by default Create a separate snapshot with the mobile URL or enable responsive tracking in snapshot settings
Too many snapshots running, data is thin Active snapshot limit reached; traffic is split across many snapshots Pause unused snapshots to concentrate traffic on the ones you are actively analyzing

Performance Considerations

The Crazy Egg script weighs approximately 20 KB gzipped and loads asynchronously. It does not block the critical rendering path and has minimal impact on Core Web Vitals when loaded with the async attribute.

Session recordings add overhead because the SDK must observe DOM mutations and capture mouse/scroll events. On pages with heavy DOM manipulation (real-time dashboards, chat interfaces), recording can increase CPU usage by 2-5%. If this is a concern, exclude high-activity pages from recordings using URL filters in the Crazy Egg dashboard.

A/B tests that modify the DOM can cause a flash of original content (FOOC) if the Crazy Egg script loads after the initial paint. To mitigate this:

/* Hide the tested element until Crazy Egg applies the variant */
.ab-test-target {
  visibility: hidden;
}
// Crazy Egg will set visibility: visible when the variant is applied
// Add a fallback timeout so the element shows even if the script fails
setTimeout(function () {
  var el = document.querySelector('.ab-test-target');
  if (el) el.style.visibility = 'visible';
}, 2000);

Limit the number of active snapshots to what you are actively analyzing. Each active snapshot records data independently, and running 50 snapshots when you only review 5 wastes your plan's pageview quota.