Analytics
Dette indhold er ikke tilgængeligt i dit sprog endnu.
The Deepdots Popup SDK includes a built-in analytics layer that collects behavioral data from your users and forwards it to a dedicated integration in your Deepdots workspace. This lets you measure engagement, navigation patterns, and business-critical events without adding a separate analytics tool.
Add an analytics object to init() with the publicKey and integration ID of the integration created in your Deepdots workspace. Without it the SDK runs in dry-run mode — all events are logged to the console but nothing is sent.
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
const popups = new DeepdotsPopups();popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', analytics: { publicKey: 'YOUR_ANALYTICS_PUBLIC_KEY', integration: 'YOUR_INTEGRATION_ID', },});Automatic data
Section titled “Automatic data”The following data is collected with zero extra code as long as the SDK is initialized:
| Data | How | Where it appears |
|---|---|---|
Screen views (page_view) | History API (pushState / popstate / hashchange) | Events |
Active engagement time (user_engagement) | visibilitychange listener | Events |
Persistent user identity (user_id) | Generated on first visit, stored in localStorage | Metadata |
| Device type | Parsed from User-Agent (mobile / tablet / desktop) | Context |
| User agent | navigator.userAgent | Context |
| Browser language | navigator.language | Context |
| App version | appVersion passed to init() | Context |
Each flush (tab hidden, page closed, or manual flushAnalytics()) sends the accumulated events as a batch. The backend groups batches by session so you see a single timeline per user visit, not one record per flush.
Custom events
Section titled “Custom events”Use track(name, params?) to record any business event. Event names are free-form strings — use lowercase snake_case to stay consistent with the automatic events.
popups.track('add_to_cart', { product_id: 'p-123', value: 49.9, currency: 'EUR' });popups.track('checkout_started');popups.track('plan_upgraded', { plan: 'pro', billing: 'annual' });Search
Section titled “Search”trackSearch records a search query together with the number of results. The SDK automatically adds has_results: boolean from the count.
popups.trackSearch('running shoes', 0); // no results — has_results: falsepopups.trackSearch('t-shirt', 142); // has_results: trueFindability friction
Section titled “Findability friction”Record moments where users struggle to find what they need:
popups.trackFindabilityFriction('checkout_address');popups.trackFindabilityFriction('plan_comparison');Funnel steps
Section titled “Funnel steps”Track steps inside a named funnel. Group related steps under the same funnel and taskId so the backend can compute conversion rates:
popups.trackFunnelStep('onboarding', 'account_created', 'task-42');popups.trackFunnelStep('onboarding', 'profile_completed', 'task-42');popups.trackFunnelStep('onboarding', 'first_popup_seen', 'task-42');Mini-service tracking
Section titled “Mini-service tracking”A mini-service is any bounded workflow inside your app (checkout flow, onboarding wizard, support chat). The SDK tracks entry, exit, and duration automatically once you signal the boundaries:
// User enters the checkout flowpopups.enterMiniService('checkout', 'home_banner');
// … user completes or abandons the flow …
// User leaves — duration is computed automaticallypopups.exitMiniService();Any survey shown while a mini-service is active automatically receives a mini_service metadata tag, which lets you filter CSAT results by workflow context in Deepdots.
User attributes
Section titled “User attributes”Call setUserAttributes to attach business-level attributes to the user’s analytics context. These are included in every subsequent flush.
popups.setUserAttributes({ plan: 'pro', registration_status: 'registered', sector: 'retail',});Attributes are cumulative — each call merges with previously set ones.
Contact record
Section titled “Contact record”setContactAttributes sends the attributes to POST /sdk/popups/contact, creating or updating the user’s contact record in Deepdots. This endpoint is only called when a userId was provided in init() and tracking is enabled.
const sent = await popups.setContactAttributes({ language: 'en', age: 34, plan: 'premium' });// sent: true if a POST was made, false if attributes haven't changed (deduplication)You can also pass contactAttributes directly in init() to fire the contact update on startup:
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', userId: 'user-123', contactAttributes: { plan: 'premium', language: 'en' },});Privacy and consent
Section titled “Privacy and consent”Set trackingEnabled: false in init() to start with all analytics and contact tracking disabled — useful when you need explicit user consent before collecting data.
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', trackingEnabled: false,});
// Later, once the user gives consent:popups.setTrackingEnabled(true);setTrackingEnabled(false) suspends all outbound calls (analytics, contact). setTrackingEnabled(true) resumes them and assigns a persistent user_id if one was not already stored.
React Native
Section titled “React Native”In React Native, two automatic behaviors require explicit host integration:
Navigation tracking
Section titled “Navigation tracking”Because History API is unavailable, report screen changes manually after each navigation event:
// In React Navigation's onStateChange callback:popups.setScreen(route.name);Lifecycle (engagement time)
Section titled “Lifecycle (engagement time)”Connect the SDK to the app’s foreground/background lifecycle so engagement time is measured correctly and events are flushed when the app goes to the background:
import { AppState } from 'react-native';
AppState.addEventListener('change', (state) => { if (state === 'active') popups.onForeground(); else popups.onBackground(); // also flushes pending analytics});Previewing events before sending
Section titled “Previewing events before sending”During development, inspect the current event buffer without flushing:
const preview = popups.previewAnalytics();console.log(preview.events); // all events queued since last flushTo force a flush manually (useful for testing):
popups.flushAnalytics();