🔮 Sypnia SDK Playground

Test the SDK locally before integrating into your projects

📋 SDK Script

// ==========================================
// 🔮 SYPNIA SDK - Paste this in your project
// ==========================================
(function() {
  'use strict';

  const SYPNIA_CONFIG = {
    // TODO: Replace with your actual endpoint when ready
    endpoint: 'http://localhost:3000/api/track',
    projectKey: 'test-project-key',
    debug: true // Set to false in production
  };

  // Generate or retrieve session ID
  function getSessionId() {
    let sessionId = sessionStorage.getItem('sypnia_session_id');
    if (!sessionId) {
      sessionId = 'sess_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
      sessionStorage.setItem('sypnia_session_id', sessionId);
    }
    return sessionId;
  }

  // Generate or retrieve visitor ID (persistent)
  function getVisitorId() {
    let visitorId = localStorage.getItem('sypnia_visitor_id');
    if (!visitorId) {
      visitorId = 'vis_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
      localStorage.setItem('sypnia_visitor_id', visitorId);
    }
    return visitorId;
  }

  // Get device info
  function getDeviceInfo() {
    const ua = navigator.userAgent;
    return {
      browser: ua.includes('Chrome') ? 'Chrome' : 
               ua.includes('Firefox') ? 'Firefox' : 
               ua.includes('Safari') ? 'Safari' : 'Other',
      device_type: /Mobile|Android|iPhone/i.test(ua) ? 'mobile' : 'desktop',
      screen_width: window.screen.width,
      screen_height: window.screen.height
    };
  }

  // Core tracking function
  function track(eventType, payload = {}) {
    const event = {
      type: eventType,
      session_id: getSessionId(),
      visitor_id: getVisitorId(),
      url: window.location.href,
      path: window.location.pathname,
      referrer: document.referrer,
      timestamp: new Date().toISOString(),
      project_key: SYPNIA_CONFIG.projectKey,
      device: getDeviceInfo(),
      payload: payload
    };

    // 🔥 DEBUG: Print to console
    if (SYPNIA_CONFIG.debug) {
      console.log('%c🔮 SYPNIA EVENT', 'background: #6366f1; color: white; padding: 4px 8px; border-radius: 4px;', eventType);
      console.log('   Payload:', event);
    }

    // Send to server (non-blocking)
    if (navigator.sendBeacon) {
      navigator.sendBeacon(SYPNIA_CONFIG.endpoint, JSON.stringify(event));
    } else {
      fetch(SYPNIA_CONFIG.endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(event),
        keepalive: true
      }).catch(() => {});
    }

    return event;
  }

  // ==========================================
  // EVENT LISTENERS
  // ==========================================

  // 📄 PAGEVIEW - Track on load
  function trackPageview() {
    track('pageview', {
      title: document.title,
      referrer: document.referrer
    });
  }

  // 🖱️ CLICK TRACKING with Rage Click Detection
  let clickQueue = [];
  let lastClickTarget = null;

  function trackClick(e) {
    const target = e.target;
    const selector = getSelector(target);
    const now = Date.now();

    // Rage click detection (5 clicks in < 1 second on same element)
    clickQueue.push({ target: selector, time: now });
    clickQueue = clickQueue.filter(c => now - c.time < 1000);
    
    const sameElementClicks = clickQueue.filter(c => c.target === selector);
    
    if (sameElementClicks.length >= 5) {
      track('rage_click', {
        selector: selector,
        click_count: sameElementClicks.length,
        element_text: target.innerText?.substring(0, 100)
      });
      clickQueue = []; // Reset after detecting rage click
    } else {
      track('click', {
        selector: selector,
        element_text: target.innerText?.substring(0, 100),
        tag: target.tagName.toLowerCase()
      });
    }
  }

  // 🔴 ERROR TRACKING
  function trackError(message, source, lineno, colno, error) {
    track('error', {
      message: message,
      source: source,
      line: lineno,
      column: colno,
      stack: error?.stack?.substring(0, 1000)
    });
  }

  // Unhandled promise rejection
  function trackUnhandledRejection(event) {
    track('error', {
      message: 'Unhandled Promise Rejection',
      reason: String(event.reason).substring(0, 500)
    });
  }

  // Get CSS selector for element
  function getSelector(el) {
    if (!el) return '';
    if (el.id) return '#' + el.id;
    if (el.className && typeof el.className === 'string') {
      const classes = el.className.split(' ').filter(c => c).slice(0, 2).join('.');
      if (classes) return el.tagName.toLowerCase() + '.' + classes;
    }
    return el.tagName.toLowerCase();
  }

  // ==========================================
  // INITIALIZE
  // ==========================================
  
  // Attach listeners
  window.addEventListener('load', trackPageview);
  document.addEventListener('click', trackClick);
  window.onerror = trackError;
  window.addEventListener('unhandledrejection', trackUnhandledRejection);

  // Expose global API
  window.Sypnia = {
    track: track,
    identify: (userId, traits = {}) => track('identify', { user_id: userId, traits }),
    feedback: (score, message) => track('feedback', { score, message })
  };

  console.log('%c🔮 Sypnia SDK Loaded', 'background: #6366f1; color: white; padding: 4px 8px; border-radius: 4px; font-weight: bold;');
  console.log('   Debug mode:', SYPNIA_CONFIG.debug);
  console.log('   Session ID:', getSessionId());
  console.log('   Visitor ID:', getVisitorId());
})();

📝 How to Use

  1. Copy the SDK script above
  2. Paste it in a <script> tag in your HTML
  3. Or add it to your JS bundle
  4. Open browser console to see tracked events
  5. Events will print with 🔮 SYPNIA EVENT prefix

🧪 Test Events

Console Output

Click buttons above to simulate events...

⚡ Quick Integration

Add this single line to your HTML before the closing </body> tag:

<script>
  // Paste the SDK code here
</script>

🎯 Custom Events API

After loading the SDK, you can track custom events:

// Track custom event
Sypnia.track('button_click', { button_id: 'cta' });

// Identify user
Sypnia.identify('user123', { plan: 'pro' });

// Send feedback
Sypnia.feedback(5, 'Great product!');