> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/MagicFeedback/deepdots-popup-sdk/llms.txt
> Use this file to discover all available pages before exploring further.

# Event Triggers

> Learn how to trigger popups from business events in your application

Event triggers allow you to show popups in response to business logic and user behavior that goes beyond simple DOM interactions. Instead of relying on time, scroll, or click triggers, you can fire popups when specific actions occur in your application.

## When to Use Event Triggers

Use event triggers when popup logic depends on product behavior:

* **Search behavior**: Show feedback after repeated searches with low engagement
* **Feature usage**: Collect input after a user completes a specific workflow
* **Error states**: Request feedback when users encounter issues
* **Milestones**: Celebrate achievements and gather sentiment
* **Business rules**: Fire popups based on complex conditions in your app

<Tip>
  Event triggers give you full control over popup timing based on your application's state and business logic.
</Tip>

## How It Works

<Steps>
  <Step title="Define an event-based popup">
    Create a popup definition with `type: 'event'` and specify the event name:

    <CodeGroup>
      ```typescript Client Mode theme={null}
      const popupDefinitions = [
        {
          id: 'popup-search-event',
          title: 'Help us improve search',
          message: '<p>Did you find what you were looking for?</p>',
          triggers: {
            type: 'event',
            value: 'search', // Your custom event name
            condition: [{ answered: false, cooldownDays: 3 }],
          },
          surveyId: 'survey-search-001',
          productId: 'product-main',
          actions: {
            accept: {
              label: 'Share Feedback',
              surveyId: 'survey-search-001',
            },
          },
        },
      ];
      ```

      ```typescript Server Mode theme={null}
      // In server mode, define event triggers in your Deepdots dashboard
      // The popup definition will include:
      // triggers: { type: 'event', value: 'search' }
      ```
    </CodeGroup>
  </Step>

  <Step title="Initialize the SDK">
    ```typescript theme={null}
    import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

    const popups = new DeepdotsPopups();

    popups.init({
      mode: 'server', // or 'client'
      apiKey: 'YOUR_API_KEY',
      debug: true,
    });

    popups.autoLaunch();
    ```
  </Step>

  <Step title="Trigger the event from your code">
    Call `triggerEvent()` when your business logic determines a popup should appear:

    ```typescript theme={null}
    // In your application code
    function handleSearch(query) {
      // Your search logic...
      performSearch(query);
      
      // Trigger the popup
      popups.triggerEvent('search');
    }
    ```
  </Step>
</Steps>

## Real-World Example: Search Intent Detection

This example from the casino demo shows how to track search behavior and trigger popups based on user intent signals:

```typescript theme={null}
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

const SEARCH_EVENT_NAME = 'search';
const SEARCH_WINDOW_MS = 120 * 1000; // 2 minutes
const SEARCH_EVENT_DEDUP_MS = 1200; // Dedup window

// Track search behavior
const searchBehavior = {
  searchTimestamps: [],
  lastSearchResultClickAt: 0,
  lastEventEmitAt: 0,
};

const sdk = new DeepdotsPopups();
sdk.init({
  mode: 'server',
  nodeEnv: 'production',
  debug: true,
  apiKey: 'YOUR_API_KEY',
  userId: 'customer-123',
});
sdk.autoLaunch();

// Evaluate search actions and emit SDK events
function registerSearchAction(query) {
  const normalized = String(query || '').trim().toLowerCase();
  if (normalized.length < 2) return;

  const now = Date.now();
  
  // Remove old searches outside the time window
  searchBehavior.searchTimestamps = searchBehavior.searchTimestamps
    .filter(ts => ts >= now - SEARCH_WINDOW_MS);
  
  searchBehavior.searchTimestamps.push(now);

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

  // Rule 1: Three searches in 2 minutes
  if (searchesInWindow >= 3) {
    emitSearchEvent('three_searches_120s');
    return;
  }

  // Rule 2: Two searches without clicking results
  if (searchesSinceLastClick >= 2) {
    emitSearchEvent('two_searches_no_click');
    return;
  }
}

// Track when user clicks a search result
function markSearchResultClick() {
  searchBehavior.lastSearchResultClickAt = Date.now();
}

// Emit the search event with deduplication
function emitSearchEvent(reason) {
  const now = Date.now();
  if (now - searchBehavior.lastEventEmitAt < SEARCH_EVENT_DEDUP_MS) {
    return; // Too soon, skip
  }

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

// Use in your app
document.querySelector('#search-input').addEventListener('input', (e) => {
  registerSearchAction(e.target.value);
});

document.querySelectorAll('.search-result').forEach(result => {
  result.addEventListener('click', markSearchResultClick);
});
```

<Note>
  This example tracks search intent by monitoring:

  * Number of searches in a time window
  * Whether users click on search results
  * Time since last popup to avoid flooding
</Note>

## Simple Event Trigger Example

For simpler use cases, trigger events directly:

```typescript theme={null}
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

const popups = new DeepdotsPopups();

popups.init({
  mode: 'server',
  apiKey: 'YOUR_API_KEY',
});

popups.autoLaunch();

// Trigger on button click
document.querySelector('#feedback-button').addEventListener('click', () => {
  popups.triggerEvent('feedback-button-click');
});

// Trigger after form submission
function handleFormSubmit(form) {
  // Submit form...
  submitForm(form);
  
  // Request feedback
  popups.triggerEvent('form-submitted');
}

// Trigger on error
function handleError(error) {
  logError(error);
  popups.triggerEvent('error-occurred');
}
```

## API Reference

### `triggerEvent(eventName)`

Shows the first eligible popup whose definition contains:

```typescript theme={null}
triggers: { type: 'event', value: eventName }
```

**Parameters:**

* `eventName` (string): The name of the event to trigger. Must match the `value` field in your popup definition.

**Example:**

```typescript theme={null}
popups.triggerEvent('search');
popups.triggerEvent('checkout-complete');
popups.triggerEvent('feature-used');
```

**Behavior:**

* Finds all popup definitions with matching event triggers
* Evaluates conditions (`answered`, `cooldownDays`) and segments
* Shows the first eligible popup
* Logs debug info if no matching popups are found

<Warning>
  The event name is **case-sensitive** and must match exactly. `'Search'` and `'search'` are different events.
</Warning>

## Event Trigger Conditions

Control when event-triggered popups can fire:

```typescript theme={null}
triggers: {
  type: 'event',
  value: 'search',
  condition: [
    {
      answered: false,      // Only show if survey not completed
      cooldownDays: 3       // Wait 3 days between shows
    }
  ]
}
```

* **`answered: false`**: Popup won't show if user already completed the survey
* **`cooldownDays`**: Minimum days between popup displays for this definition

## Best Practices

<AccordionGroup>
  <Accordion title="Use descriptive event names">
    Choose clear, specific event names that describe the business action:

    ```typescript theme={null}
    // Good
    popups.triggerEvent('checkout-abandoned');
    popups.triggerEvent('trial-ending-soon');
    popups.triggerEvent('feature-discovery');

    // Avoid
    popups.triggerEvent('event1');
    popups.triggerEvent('popup');
    ```
  </Accordion>

  <Accordion title="Implement deduplication">
    Prevent flooding by tracking when you last triggered an event:

    ```typescript theme={null}
    let lastTriggerTime = 0;
    const DEDUP_WINDOW_MS = 5000; // 5 seconds

    function triggerWithDedup(eventName) {
      const now = Date.now();
      if (now - lastTriggerTime < DEDUP_WINDOW_MS) {
        return; // Skip duplicate
      }
      lastTriggerTime = now;
      popups.triggerEvent(eventName);
    }
    ```
  </Accordion>

  <Accordion title="Combine with business logic">
    Evaluate complex conditions before triggering:

    ```typescript theme={null}
    function handleFeatureUsage(feature) {
      const usageCount = getFeatureUsageCount(feature);
      const userTier = getCurrentUserTier();
      
      // Only trigger for power users
      if (usageCount > 10 && userTier === 'pro') {
        popups.triggerEvent('power-user-feedback');
      }
    }
    ```
  </Accordion>

  <Accordion title="Respect user intent">
    Don't trigger popups during critical workflows:

    ```typescript theme={null}
    function shouldTriggerFeedback() {
      // Avoid interrupting checkout
      if (isCheckoutInProgress()) return false;
      
      // Avoid during onboarding
      if (isOnboardingActive()) return false;
      
      return true;
    }

    if (shouldTriggerFeedback()) {
      popups.triggerEvent('general-feedback');
    }
    ```
  </Accordion>
</AccordionGroup>

## Debugging Event Triggers

Enable debug mode to see event trigger logs:

```typescript theme={null}
popups.init({
  mode: 'server',
  apiKey: 'YOUR_API_KEY',
  debug: true, // Enable logging
});
```

The SDK will log:

* When `triggerEvent()` is called
* Which popup definitions match the event name
* Why popups were blocked (conditions, segments, etc.)
* When popups are shown

## Next Steps

<CardGroup cols={2}>
  <Card title="Exit Popups" icon="door-open" href="/guides/exit-popups">
    Show popups when users navigate away
  </Card>

  <Card title="Route Targeting" icon="route" href="/guides/route-targeting">
    Target popups to specific pages
  </Card>

  <Card title="Server Mode" icon="server" href="/guides/server-mode">
    Manage event triggers remotely
  </Card>

  <Card title="Client Mode" icon="code" href="/guides/client-mode">
    Define event triggers inline
  </Card>
</CardGroup>
