Skip to main content
Triggers determine when and how popups are displayed to users. The SDK supports five trigger types, each designed for different user interaction patterns.

Trigger Types Overview

The SDK supports the following trigger types:
  • time_on_page - Shows popup after a specified time on page
  • scroll - Shows popup after reaching a scroll percentage
  • click - Shows popup after clicking a specific element
  • exit - Shows popup after leaving a route (deferred to next page)
  • event - Shows popup when your application fires a custom event

Time on Page

Shows the popup after the user has been on the page for a specified duration.
// Popup definition fetched from API
{
  id: 'popup-home-5s',
  title: 'Quick feedback',
  message: '<p>How is your experience so far?</p>',
  triggers: {
    type: 'time_on_page',
    value: 5, // seconds
    condition: [{ answered: false, cooldownDays: 7 }]
  },
  surveyId: 'survey-home-001',
  productId: 'product-main'
}
Configuration:
  • value: Number of seconds to wait before showing the popup
  • Timer starts when autoLaunch() is called
  • Timer does not reset on route changes within the same session
In popup definitions, time_on_page values are always in seconds. The SDK internally converts them to milliseconds.

Scroll Trigger

Shows the popup when the user scrolls to a specific percentage of the page.
{
  id: 'popup-scroll-50',
  title: 'Enjoying our content?',
  message: '<p>Let us know what you think!</p>',
  triggers: {
    type: 'scroll',
    value: 50, // Show at 50% scroll depth
    condition: [{ answered: false, cooldownDays: 14 }]
  },
  surveyId: 'survey-content-002',
  productId: 'product-main'
}
Configuration:
  • value: Scroll percentage threshold (0-100)
  • Triggers once when threshold is reached
  • Scroll percentage is calculated as: (scrollY / (totalHeight - viewportHeight)) * 100
Common Use Cases:
  • Feedback on long-form content (50-75% scroll)
  • Exit intent alternative for engaged readers (90% scroll)
  • Mid-article engagement (25-30% scroll)

Click Trigger

Shows the popup when the user clicks on a specific DOM element.
{
  id: 'popup-button-click',
  title: 'Tell us more',
  message: '<p>What made you click that button?</p>',
  triggers: {
    type: 'click',
    value: 'feedback-button', // Element ID
  },
  surveyId: 'survey-click-003',
  productId: 'product-main'
}
Configuration:
  • value: The id attribute of the target element (string)
  • Triggers immediately when element is clicked
  • Automatically removes listener after first trigger
HTML Example:
<button id="feedback-button">Give Feedback</button>
If the element doesn’t exist when autoLaunch() is called, the SDK waits for DOMContentLoaded and tries again.

Exit Trigger

Queues a popup when the user navigates away from a matching route, then shows it on the destination page after a specified delay.
{
  id: 'popup-pricing-exit',
  title: 'Before you go',
  message: '<p>Any questions about our pricing?</p>',
  triggers: {
    type: 'exit',
    value: 3, // Show 3 seconds after arriving at next page
    condition: [{ answered: false, cooldownDays: 30 }]
  },
  surveyId: 'survey-pricing-004',
  productId: 'product-main',
  segments: {
    path: ['/pricing'] // Only trigger when leaving /pricing
  }
}
Configuration:
  • value: Delay in seconds before showing popup on the new page
  • Uses sessionStorage to persist queued popups across page loads
  • Supports all navigation types: anchor clicks, pushState, replaceState, hash navigation
How It Works:
  1. User is on a page matching segments.path
  2. User navigates to a different route
  3. SDK queues the popup in sessionStorage
  4. On the new page, SDK waits for the specified delay
  5. Popup is shown if conditions are met
  • Popup only shows if the destination URL is different from the source URL
  • Popup is dropped if user navigates back to the original URL before delay expires
  • Multiple exit popups can be queued, but only one will show (first eligible)
  • Queue is cleared when popup is shown or conditions fail
  • Works with SPAs and traditional multi-page apps
Exit triggers evaluate segments.path against the source route (where user is leaving from), not the destination route.

Event Trigger

Shows popups in response to custom events fired by your application. This is the most flexible trigger type for product-driven feedback flows.
{
  id: 'popup-search-event',
  title: 'Search feedback',
  message: '<p>Tell us about your search experience</p>',
  triggers: {
    type: 'event',
    value: 'search_completed', // Custom event name
    condition: [{ answered: false, cooldownDays: 7 }]
  },
  surveyId: 'survey-search-005',
  productId: 'product-main'
}
Triggering from Your Application:
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';

const popups = new DeepdotsPopups();

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

popups.autoLaunch();

// Later, when user completes a search
function onSearchComplete(query, results) {
  // Your search logic...
  
  // Trigger feedback popup
  popups.triggerEvent('search_completed');
}
Configuration:
  • value: Custom event name (string)
  • Must match exactly when calling triggerEvent(eventName)
  • Event names are case-sensitive
Common Use Cases:
// After checkout completion
popups.triggerEvent('purchase_completed');
Event triggers are not automatically activated by autoLaunch(). They only respond to explicit triggerEvent() calls from your application.

Trigger Conditions

All trigger types support optional conditions that control when popups are shown:
triggers: {
  type: 'time_on_page',
  value: 5,
  condition: [
    {
      answered: false,      // Don't show if user already answered
      cooldownDays: 7       // Wait 7 days before showing again
    }
  ]
}

Condition Fields

FieldTypeDescription
answeredbooleanIf false, popup won’t show if user has answered the survey
cooldownDaysnumberMinimum days between popup displays
Conditions are evaluated as an array, and all conditions must pass for the popup to show. Multiple conditions are combined with AND logic.

Path Targeting

All triggers can be restricted to specific routes using segments.path:
{
  id: 'popup-docs-only',
  triggers: { type: 'time_on_page', value: 10 },
  segments: {
    path: [
      '/docs',
      '/docs/getting-started',
      '/#/documentation'
    ]
  },
  // ... other fields
}
Path Matching Rules:
  • Full URLs: https://example.com/pricing (exact match)
  • Path fragments: /pricing (matches if current URL includes this path)
  • Hash routes: /#/home (matches hash-based routes)
  • If segments.path is empty or not provided, popup can trigger on any route
Path matching normalizes URLs by removing trailing slashes and /index.html suffixes for consistent comparison.

Manual Triggering

You can bypass triggers and show popups immediately using these methods:
// Show by survey and product ID
popups.show({
  surveyId: 'survey-001',
  productId: 'product-main'
});

// Show by popup definition ID
popups.showByPopupId('popup-home-5s');
Manual triggering with show() or showByPopupId() still respects conditions and path segments.

Build docs developers (and LLMs) love