How Lucky Orange Works
Lucky Orange is a conversion optimization platform that combines session recordings, dynamic heatmaps, form analytics, conversion funnels, live chat, and surveys in a single JavaScript tag. Unlike static heatmap tools that snapshot a page at a point in time, Lucky Orange generates heatmaps dynamically from recorded session data, meaning you can filter and regenerate heatmaps at any time without waiting for new data to accumulate.
The data collection model is recording-first. When the Lucky Orange script loads, it begins capturing the full visitor session: DOM state, mouse coordinates, scroll position, click targets, form interactions, and page transitions. This raw session data is processed server-side to generate heatmaps, form analytics, and funnel reports. Because everything derives from the same session recording, you can always drill from an aggregate metric down to the individual sessions behind it.
Lucky Orange uses a combination of DOM snapshotting and mutation observation to capture the page state. The initial snapshot records the full HTML, CSS, and computed styles. Subsequent changes are captured as lightweight diffs (DOM mutations, style changes, attribute updates). This keeps the recording payload small, typically 50-200 KB per minute of session activity, while preserving full visual fidelity during playback.
Session data is stored on Lucky Orange's servers for 30-90 days depending on your plan. During that retention window, you can generate heatmaps, filter recordings, and build funnels from the stored data. After retention expires, aggregate statistics persist but individual recordings are purged.
Installing the Lucky Orange Script
Add the Lucky Orange tracking script before the closing </head> tag. The site ID is available in your Lucky Orange dashboard under Settings > Tracking Code.
<script type="text/javascript">
window.__lo_site_id = YOUR_SITE_ID;
(function () {
var wa = document.createElement('script');
wa.type = 'text/javascript';
wa.async = true;
wa.src = 'https://d10lpsik1i8c69.cloudfront.net/w.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wa, s);
})();
</script>
Replace YOUR_SITE_ID with your numeric site ID (e.g., 123456).
Loading via Google Tag Manager
Create a Custom HTML tag in GTM:
<script type="text/javascript">
window.__lo_site_id = YOUR_SITE_ID;
(function () {
var wa = document.createElement('script');
wa.type = 'text/javascript';
wa.async = true;
wa.src = 'https://d10lpsik1i8c69.cloudfront.net/w.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wa, s);
})();
</script>
Set the trigger to All Pages. Fire this tag with high priority (or tag sequencing) so it loads before any tags that depend on the Lucky Orange API.
Verifying Installation
Open your site in a browser and check the Network tab in DevTools. Filter for cloudfront.net/w.js. You should see a successful request (200 status).
You can also check programmatically:
// Returns true if Lucky Orange is loaded
if (typeof window.__lo_cs_added !== 'undefined') {
console.log('Lucky Orange is active');
}
In the Lucky Orange dashboard, go to Recordings. Your session should appear within 1-2 minutes.
Core Tracking Features
Session Recordings
Recordings start automatically when the script loads. Every visitor session is captured, including:
- Mouse movements and click locations
- Scroll depth and scroll speed
- Page transitions (multi-page and SPA)
- Form field focus, input, and submission
- Rage clicks (rapid repeated clicks)
- Dead clicks (clicks on non-interactive elements)
- JavaScript errors that occur during the session
Lucky Orange automatically masks sensitive form fields (password, credit card) by default. You can extend masking to additional elements:
<!-- Add the data-lo-block attribute to hide content from recordings -->
<div data-lo-block>
<p>This content will not appear in recordings</p>
<input type="text" name="ssn" />
</div>
<!-- Mask specific input fields -->
<input type="text" name="phone" data-lo-mask />
Dynamic Heatmaps
Lucky Orange heatmaps are generated on-demand from recorded session data. You can filter heatmaps by:
- Date range
- Device type (desktop, tablet, mobile)
- Traffic source / referrer
- Country or region
- New vs. returning visitors
- Custom tags
Three heatmap types are available:
Click heatmaps show where visitors click, including clicks on non-interactive elements (dead clicks). The overlay uses a gradient from blue (low) to red (high activity).
Scroll heatmaps show what percentage of visitors reached each vertical position on the page. A color gradient indicates the fold line for different visitor segments.
Move heatmaps track mouse movement patterns, which correlate with visual attention on desktop. Areas where the mouse lingers indicate content that caught the visitor's eye.
Form Analytics
Lucky Orange automatically detects forms and tracks field-level metrics:
- Field drop-off rate: percentage of visitors who started the form but abandoned at each field
- Time per field: average seconds spent on each input
- Error rate: how often validation errors appear per field
- Refill rate: how often visitors clear and re-enter a field (indicates confusion)
- Abandonment point: the last field interacted with before leaving
No additional code is needed for form analytics. Lucky Orange detects <form> elements and their child inputs automatically.
Custom Event Tracking and Tagging
Tagging Recordings
Tag recordings with custom metadata to make them searchable:
// Tag the current session with custom labels
if (window.LOQ) {
window.LOQ.push(['ready', function (LO) {
LO.$internal.ready('visitor').then(function () {
LO.visitor.tag('premium-user');
LO.visitor.tag('plan:enterprise');
LO.visitor.tag('segment:high-value');
});
}]);
}
Identifying Visitors
Attach a name and email to the recording so you can search for specific users:
if (window.LOQ) {
window.LOQ.push(['ready', function (LO) {
LO.$internal.ready('visitor').then(function () {
LO.visitor.identify({
name: 'Jane Martinez',
email: 'jane@acme.com'
});
});
}]);
}
Tracking Custom Events
Log custom events that appear as markers on the recording timeline:
if (window.LOQ) {
window.LOQ.push(['ready', function (LO) {
LO.$internal.ready('events').then(function () {
LO.events.track('Added to Cart', {
product: 'Pro Plan',
price: 49.99,
currency: 'USD'
});
});
}]);
}
These events appear as clickable markers during recording playback, so you can jump directly to the moment a visitor triggered an event.
SPA Page Tracking
Lucky Orange automatically detects URL changes from pushState and replaceState. For frameworks that use hash-based routing, Lucky Orange also watches hashchange events. No additional configuration is needed for most single-page applications.
If your SPA uses a custom routing mechanism that does not trigger pushState or hashchange, manually notify Lucky Orange:
// After custom route change
if (window.LOQ) {
window.LOQ.push(['ready', function (LO) {
LO.$internal.ready('pageview').then(function () {
LO.pageview();
});
}]);
}
Conversion Funnels
Define multi-step conversion funnels in the Lucky Orange dashboard. Steps can be URLs, custom events, or page elements. Funnels show:
- Conversion rate between each step
- Average time between steps
- Drop-off volume at each step
- Direct links to recordings of visitors who dropped off
To create a funnel, go to Funnels in the dashboard and add steps. For example, a checkout funnel:
- Visited
/products(URL step) - Visited
/cart(URL step) - Visited
/checkout(URL step) - Custom event
purchase_completed(event step)
Because funnels are built from recording data, you can retroactively create funnels and apply them to historical sessions within your retention window.
Integration with Other Tools
Forwarding Events to GA4 via Data Layer
Track the same events in both Lucky Orange and GA4:
function trackLOAndGA4(eventName, properties) {
// Lucky Orange
if (window.LOQ) {
window.LOQ.push(['ready', function (LO) {
LO.$internal.ready('events').then(function () {
LO.events.track(eventName, properties);
});
}]);
}
// GA4 via GTM dataLayer
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'lo_' + eventName.toLowerCase().replace(/\s+/g, '_'),
...properties
});
}
trackLOAndGA4('Form Submitted', { form_name: 'contact', page: '/contact-us' });
Shopify Integration
Lucky Orange has a native Shopify app that installs the tracking code automatically and maps Shopify-specific events (add to cart, begin checkout, purchase) to Lucky Orange events. Install from the Shopify App Store, then connect your Lucky Orange account.
WordPress Integration
Install the Lucky Orange WordPress plugin from the plugin directory. Enter your site ID in the plugin settings. The plugin injects the tracking script on all pages and adds a Lucky Orange dashboard widget to the WordPress admin.
Common Errors
| Error | Cause | Fix |
|---|---|---|
| No recordings appearing in dashboard | Script blocked by ad blocker or Content Security Policy | Add d10lpsik1i8c69.cloudfront.net and *.luckyorange.com to CSP script-src and connect-src |
| Recordings show a blank white page | CSS resources blocked by CORS policy during playback reconstruction | Add Access-Control-Allow-Origin: * to your CSS and font file responses |
__lo_cs_added is undefined |
Lucky Orange script has not finished loading | Wait for the script to load before checking; use window.LOQ.push(['ready', ...]) for all API calls |
| Heatmap shows clicks in wrong positions | Page layout changed since recordings were captured, or dynamic content shifts elements | Heatmaps are generated from current recordings; the element mapping may drift if the DOM changes significantly between sessions |
| Form analytics shows 0 forms | Forms are rendered dynamically after page load and Lucky Orange scanned before they existed | Lucky Orange re-scans periodically, but for late-rendered forms, ensure they appear within a few seconds of page load |
| Session recordings cut off mid-visit | Visitor navigated to a page where the Lucky Orange script is not installed | Install the script on all pages across your site |
| Tags not appearing in recording filters | visitor.tag() called before the visitor module was ready |
Always use the LOQ.push(['ready', ...]) pattern before calling any API methods |
| Mobile recordings look distorted | Viewport meta tag missing or incorrect, causing layout differences between capture and playback | Ensure <meta name="viewport" content="width=device-width, initial-scale=1"> is present |
| Chat widget overlaps page content | Default chat widget position conflicts with existing page elements | Configure widget position in Lucky Orange dashboard under Chat > Appearance settings |
| Data retention shorter than expected | On the Starter plan, retention is 30 days; data older than that is purged | Upgrade to a higher plan for 60-90 day retention, or export important recordings before they expire |
Performance Considerations
The Lucky Orange script is approximately 45 KB gzipped and loads asynchronously. Initial page load impact is minimal since the script does not block rendering.
The recording engine adds overhead because it observes DOM mutations in real time. On typical marketing pages and e-commerce sites, this overhead is negligible (less than 1% CPU increase). On pages with heavy real-time DOM manipulation (live dashboards, chat interfaces, real-time editors), recording overhead can reach 3-5% CPU. If this is a concern, exclude specific pages from recording using URL filters in the Lucky Orange settings.
To minimize the impact on Largest Contentful Paint:
<!-- Defer Lucky Orange loading until after the page is interactive -->
<script type="text/javascript">
window.addEventListener('load', function () {
window.__lo_site_id = YOUR_SITE_ID;
var wa = document.createElement('script');
wa.type = 'text/javascript';
wa.async = true;
wa.src = 'https://d10lpsik1i8c69.cloudfront.net/w.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wa, s);
});
</script>
This delays recording start by a few hundred milliseconds but preserves Core Web Vitals. The trade-off is that very fast bounces (visitors who leave before the load event) will not be recorded.
Lucky Orange recordings are bandwidth-efficient. The DOM snapshot and diff approach means a 5-minute session typically generates 200-500 KB of data. This is sent to Lucky Orange servers incrementally during the session, not all at once when the visitor leaves.