Skip to main content

Overview

Sometimes you need popups to appear based on your application’s business logic, not just DOM interactions. The triggerEvent() method lets you show popups when specific business conditions are met.

Use Case: Casino Search Example

The casino demo (examples/clients/casino/) shows a real-world pattern: triggering feedback popups when users exhibit low-intent search behavior.

The Problem

A casino website wants to collect feedback from users who:
  • Search multiple times without finding what they want
  • Click a game but quickly return to search again
  • Show signs of frustration or confusion

The Solution

Track search behavior in the application and trigger a popup when patterns indicate low engagement:
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

const sdk = new DeepdotsPopups();
sdk.init({
  mode: 'server',
  nodeEnv: 'production',
  apiKey: 'YOUR_PUBLIC_API_KEY',
  userId: 'user_123',
  debug: true
});

sdk.autoLaunch();

// Trigger popup when user searches
export function triggerSearchEvent() {
  sdk.triggerEvent('search');
}

Advanced Pattern: Search Intent Tracking

The casino demo includes sophisticated logic to detect search frustration patterns:
sdk.js
const SEARCH_WINDOW_MS = 120 * 1000;  // 2 minute window
const SEARCH_BACK_WINDOW_MS = 60 * 1000;  // 1 minute for back navigation

const searchBehavior = {
  searchTimestamps: [],
  lastSearchResultClickAt: 0,
  pendingBackAfterSearchClickAt: 0,
  lastBackAfterSearchClickAt: 0,
  lastCountedQuery: '',
  lastCountedAt: 0,
  lastEventEmitAt: 0,
};

// Evaluate search and emit popup event when patterns match
function registerSearchAction(query) {
  const normalized = String(query || '').trim().toLowerCase();
  if (normalized.length < 2) return;

  const now = Date.now();
  
  // Deduplicate rapid searches
  if (searchBehavior.lastCountedQuery === normalized && 
      now - searchBehavior.lastCountedAt < 1800) {
    return;
  }
  
  searchBehavior.lastCountedQuery = normalized;
  searchBehavior.lastCountedAt = now;

  pruneOldSearches(now);
  searchBehavior.searchTimestamps.push(now);

  const searchesInWindow = searchBehavior.searchTimestamps.length;
  const searchesSinceLastClick = searchBehavior.searchTimestamps.filter(
    (timestamp) => timestamp > searchBehavior.lastSearchResultClickAt
  ).length;

  const backFlowMatched =
    searchBehavior.lastBackAfterSearchClickAt > 0 &&
    now - searchBehavior.lastBackAfterSearchClickAt <= SEARCH_BACK_WINDOW_MS;

  // Trigger conditions
  if (searchesInWindow >= 3) {
    emitSearchEvent('three_searches_120s');
    return;
  }

  if (searchesSinceLastClick >= 2) {
    emitSearchEvent('two_searches_no_click');
    return;
  }

  if (backFlowMatched) {
    emitSearchEvent('search_click_back_new_search');
    searchBehavior.lastBackAfterSearchClickAt = 0;
  }
}

function emitSearchEvent(reason) {
  if (!sdk || typeof sdk.triggerEvent !== 'function') {
    console.warn('[casino-demo] SDK not ready');
    return;
  }

  const now = Date.now();
  if (now - searchBehavior.lastEventEmitAt < 1200) {
    return;  // Debounce
  }

  searchBehavior.lastEventEmitAt = now;
  console.info('[casino-demo] triggerEvent', { 
    eventName: 'search', 
    reason 
  });
  
  sdk.triggerEvent('search');
}

Trigger Patterns

The casino example triggers a popup when:
1

Three searches in 2 minutes

User searches three times within 120 seconds without clicking results
2

Two searches with no clicks

User performs two searches without clicking any search results
3

Search → Click → Back → Search

User searches, clicks a result, navigates back within 60 seconds, then searches again

Setting Up Event Triggers

1

Configure Popup Definition

In your Deepdots dashboard or client-mode definition, create a popup with an event trigger:
{
  "id": "popup-search-feedback",
  "title": "Help us improve search",
  "message": "<p>Having trouble finding what you need?</p>",
  "triggers": {
    "type": "event",
    "value": "search"
  },
  "surveyId": "survey-search-001",
  "productId": "product-casino"
}
The triggers.value must match the event name you pass to triggerEvent()
2

Initialize SDK

import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

const sdk = new DeepdotsPopups();
sdk.init({
  mode: 'server',
  apiKey: 'YOUR_PUBLIC_API_KEY',
  userId: 'user-123',
  debug: true
});

sdk.autoLaunch();
3

Trigger From Your Code

Call triggerEvent() when your business logic condition is met:
// In your search component
function handleSearch(query) {
  // Your search logic
  performSearch(query);
  
  // Track behavior
  trackSearchBehavior(query);
  
  // Trigger popup if conditions met
  if (shouldShowFeedback()) {
    sdk.triggerEvent('search');
  }
}

Common Event Types

Here are examples of business events you might trigger:
// Cart abandonment
sdk.triggerEvent('cart-abandoned');

// Product not found
sdk.triggerEvent('search-no-results');

// Checkout issue
sdk.triggerEvent('checkout-error');

API Reference

triggerEvent(eventName)

Shows the first eligible popup whose definition contains:
triggers: { type: 'event', value: eventName }
Parameters:
  • eventName (string): The event identifier that matches your popup definition
Returns: void Example:
sdk.triggerEvent('search');
sdk.triggerEvent('checkout-error');
sdk.triggerEvent('milestone-reached');
If multiple popups match the event name, only the first eligible popup (considering conditions like cooldowns and answered state) will be shown.

Best Practices

Implement debouncing or rate limiting:
let lastTrigger = 0;
const MIN_INTERVAL = 5000; // 5 seconds

function triggerWithDebounce(eventName) {
  const now = Date.now();
  if (now - lastTrigger < MIN_INTERVAL) {
    return;
  }
  lastTrigger = now;
  sdk.triggerEvent(eventName);
}
Log additional context when the popup shows:
sdk.on('popup_shown', (event) => {
  analytics.track('Popup Shown', {
    surveyId: event.surveyId,
    trigger: 'business-event',
    userState: getCurrentUserState()
  });
});
Choose clear, descriptive names:
  • checkout-abandoned, search-frustration, feature-discovered
  • event1, popup, trigger

Testing

Test your event triggers in the browser console:
// Expose SDK globally in development
if (process.env.NODE_ENV === 'development') {
  window.__sdk = sdk;
  window.testSearchEvent = () => sdk.triggerEvent('search');
}

// Then in console:
// > testSearchEvent()

Next Steps

Basic Integration

Learn the fundamentals of SDK setup

Route Navigation

Show popups when users navigate between pages

Build docs developers (and LLMs) love