Test the SDK locally before integrating into your projects
// ==========================================
// 🔮 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());
})();<script> tag in your HTMLClick buttons above to simulate events...
Add this single line to your HTML before the closing </body> tag:
<script>
// Paste the SDK code here
</script>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!');