Lucky Orange Data Layer | Blue Frog Docs

Lucky Orange Data Layer

Set up visitor data in Lucky Orange.

Data Layer Overview

Lucky Orange's data layer allows you to enrich visitor sessions with custom information, identify specific users, and segment recordings based on visitor attributes. By implementing visitor identification and tagging, you can gain deeper insights into user behavior and create more targeted analysis.

 


 

Visitor Identification

Basic Identification

Identify visitors with custom properties to track individual users:

window._loq = window._loq || [];
_loq.push(['custom', {
  name: 'John Doe',
  email: 'john@example.com',
  customer_id: '12345'
}]);

Complete Identification

Include comprehensive user data:

window._loq = window._loq || [];
_loq.push(['custom', {
  // Identification
  user_id: 'usr_abc123',
  customer_id: '12345',
  email: 'john.doe@example.com',
  name: 'John Doe',

  // Account Information
  plan: 'professional',
  account_type: 'business',
  signup_date: '2024-01-15',

  // Behavioral Data
  lifetime_value: 4999.99,
  total_orders: 15,
  last_login: '2024-03-20',

  // Demographics
  company: 'Acme Corporation',
  industry: 'Technology',
  location: 'San Francisco, CA'
}]);

When to Identify

Call custom at these key moments:

  1. After Login: Identify user immediately after authentication
  2. On Page Load: For returning authenticated users
  3. After Registration: Capture new user information
  4. Profile Updates: When user updates their information
// After successful login
function handleLoginSuccess(user) {
  _loq.push(['custom', {
    user_id: user.id,
    email: user.email,
    name: user.fullName,
    plan: user.subscription.plan
  }]);
}

// On page load for authenticated users
if (window.currentUser) {
  _loq.push(['custom', {
    user_id: currentUser.id,
    email: currentUser.email
  }]);
}

 


 

Visitor Tagging

Basic Tags

Tag visitors to categorize and filter sessions:

window._loq = window._loq || [];

// Add single tag
_loq.push(['tag', 'VIP Customer']);

// Add multiple tags
_loq.push(['tag', 'Returning Visitor']);
_loq.push(['tag', 'Premium Plan']);
_loq.push(['tag', 'High Value']);

Dynamic Tagging

Tag based on user behavior or attributes:

// Tag based on subscription level
if (user.plan === 'enterprise') {
  _loq.push(['tag', 'Enterprise Customer']);
} else if (user.plan === 'pro') {
  _loq.push(['tag', 'Pro Customer']);
}

// Tag based on cart value
if (cartTotal > 500) {
  _loq.push(['tag', 'High Value Cart']);
}

// Tag based on user actions
document.getElementById('discount-code').addEventListener('apply', function() {
  _loq.push(['tag', 'Used Discount Code']);
});

Conditional Tags

// Tag by visitor lifecycle stage
function tagVisitorStage(user) {
  if (user.isNew) {
    _loq.push(['tag', 'New Visitor']);
  } else if (user.daysSinceSignup < 30) {
    _loq.push(['tag', 'Recent Signup']);
  } else {
    _loq.push(['tag', 'Established Customer']);
  }
}

// Tag by engagement level
if (user.loginCount > 50) {
  _loq.push(['tag', 'Power User']);
} else if (user.loginCount > 10) {
  _loq.push(['tag', 'Active User']);
}

 


 

Use Cases

E-commerce Visitor Data

window._loq = window._loq || [];

// Identify customer
_loq.push(['custom', {
  customer_id: order.customerId,
  email: order.email,
  name: order.customerName,
  lifetime_value: customer.totalSpent,
  total_orders: customer.orderCount,
  last_purchase_date: customer.lastOrderDate
}]);

// Tag customer segments
_loq.push(['tag', 'Customer Segment: ' + customer.segment]);

// Tag by cart status
if (cart.items.length > 0) {
  _loq.push(['tag', 'Active Cart']);
  _loq.push(['custom', {
    cart_value: cart.total,
    cart_items: cart.items.length
  }]);
}

SaaS Application Data

// User identification
_loq.push(['custom', {
  user_id: user.id,
  email: user.email,
  company: user.company.name,
  plan: user.subscription.plan,
  mrr: user.subscription.mrr,
  trial_end_date: user.trialEndsAt,
  feature_flags: user.enabledFeatures
}]);

// Tag by user status
_loq.push(['tag', 'User Type: ' + user.type]);
if (user.isTrial) {
  _loq.push(['tag', 'Trial User']);
}
if (user.isAdmin) {
  _loq.push(['tag', 'Admin User']);
}

Lead Scoring

let leadScore = calculateLeadScore(visitor);

_loq.push(['custom', {
  lead_score: leadScore,
  traffic_source: visitor.source,
  pages_viewed: visitor.pageViews,
  time_on_site: visitor.sessionDuration
}]);

// Tag by lead quality
if (leadScore > 80) {
  _loq.push(['tag', 'Hot Lead']);
} else if (leadScore > 50) {
  _loq.push(['tag', 'Warm Lead']);
} else {
  _loq.push(['tag', 'Cold Lead']);
}

 


 

Data Layer Best Practices

Naming Conventions

Use clear, consistent property names:

// Good - descriptive and consistent
_loq.push(['custom', {
  user_id: '123',
  email_address: 'user@example.com',
  subscription_plan: 'professional',
  account_created_date: '2024-01-01'
}]);

// Avoid - inconsistent and vague
_loq.push(['custom', {
  uid: '123',
  mail: 'user@example.com',
  plan: 'professional',
  created: '2024-01-01'
}]);

Data Privacy

Avoid sending sensitive information:

// Safe - no sensitive data
_loq.push(['custom', {
  user_id: user.id,
  email: user.email,  // Generally safe
  plan: user.plan
}]);

// Unsafe - sensitive data
_loq.push(['custom', {
  password: user.password,  // NEVER send
  credit_card: user.ccNumber,  // NEVER send
  ssn: user.socialSecurity  // NEVER send
}]);

Performance Considerations

// Good - single call with all data
_loq.push(['custom', {
  user_id: user.id,
  email: user.email,
  name: user.name,
  plan: user.plan
}]);

// Less efficient - multiple calls
_loq.push(['custom', { user_id: user.id }]);
_loq.push(['custom', { email: user.email }]);
_loq.push(['custom', { name: user.name }]);
_loq.push(['custom', { plan: user.plan }]);

 


 

Viewing Data in Dashboard

Accessing Custom Data

  1. Go to Recordings in Lucky Orange dashboard
  2. Select a recording to view
  3. Custom data appears in the Visitor Info panel
  4. Tags appear as labels on recordings

Filtering by Custom Data

  1. Navigate to RecordingsFilters
  2. Filter by Tags to find specific segments
  3. Search for specific email or user ID
  4. Filter by custom properties (plan-dependent)

Visitor Profiles

  1. Click Visitors in main navigation
  2. View individual visitor profiles
  3. See all custom data for each visitor
  4. View complete session history

 


 

Advanced Implementations

Dynamic Data Layer

// Initialize data layer object
window.dataLayer = window.dataLayer || [];

// Function to sync with Lucky Orange
function syncToLuckyOrange(data) {
  window._loq = window._loq || [];

  if (data.user) {
    _loq.push(['custom', {
      user_id: data.user.id,
      email: data.user.email,
      name: data.user.name
    }]);
  }

  if (data.tags && Array.isArray(data.tags)) {
    data.tags.forEach(tag => {
      _loq.push(['tag', tag]);
    });
  }
}

// Update data and sync
dataLayer.push({
  user: currentUser,
  tags: ['Premium', 'Authenticated']
});

syncToLuckyOrange(dataLayer[dataLayer.length - 1]);

Event-Based Identification

// Identify after specific events
document.addEventListener('userLoggedIn', function(e) {
  _loq.push(['custom', {
    user_id: e.detail.userId,
    email: e.detail.email
  }]);
  _loq.push(['tag', 'Logged In']);
});

document.addEventListener('subscriptionUpgraded', function(e) {
  _loq.push(['custom', {
    plan: e.detail.newPlan,
    upgrade_date: new Date().toISOString()
  }]);
  _loq.push(['tag', 'Recently Upgraded']);
});

 


 

Troubleshooting

Issue Cause Solution
Custom data not appearing Called before Lucky Orange loaded Ensure _loq array initialization
Tags not showing on recordings Tag not pushed correctly Verify tag syntax ['tag', 'TagName']
Data overwritten Multiple custom calls Data merges, but verify all properties sent
Special characters breaking Invalid characters in data Sanitize data before sending
Too much data Sending large objects Limit to essential properties only

 


 

Integration Examples

With JavaScript Frameworks

React:

import { useEffect } from 'react';

function App() {
  const user = useCurrentUser();

  useEffect(() => {
    if (user && window._loq) {
      window._loq.push(['custom', {
        user_id: user.id,
        email: user.email,
        plan: user.plan
      }]);
    }
  }, [user]);

  return <div>Your App</div>;
}

Vue:

export default {
  mounted() {
    if (this.$user && window._loq) {
      window._loq.push(['custom', {
        user_id: this.$user.id,
        email: this.$user.email
      }]);
    }
  }
}

 


 

Summary

  1. Identify Users: Use custom to add user properties
  2. Tag Sessions: Use tag to categorize visitors
  3. Timing Matters: Identify after login or on page load
  4. Privacy First: Never send sensitive data
  5. Be Consistent: Use standard naming conventions
  6. Filter & Analyze: Use tags to segment recordings
  7. Test Thoroughly: Verify data appears in dashboard
// SYS.FOOTER