Triggered display & runtime configuration

5 min read

Passive feedback buttons get ignored. Users are on your site to do their thing, not to hunt for a feedback form. Triggered display changes the equation: ask the right question, at the right moment, on the right page. Teams that switch from passive to triggered typically see 10-50x more responses.

FeedbackBar supports three trigger mechanisms. You can combine them freely:
  • 1. Time delay: show after N seconds on page
  • 2. Page targeting: show only on specific URLs
  • 3. Programmatic trigger: call FeedbackBar.open() from any JS event

Time delay trigger

The simplest trigger. The widget stays hidden until the user has been on the page for a set number of seconds. This avoids interrupting someone who just arrived while catching users who are lingering (and possibly confused).

Dashboard configuration

Go to your widget settings, then Customize Experience, then When & Where to Show and set the delay value. No code changes needed.

Code configuration

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: {
      showAfterSeconds: 10  // Show after 10 seconds on page
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>

Set to 0 or omit to show immediately.

When to use: Documentation pages, pricing pages, or any page where you want users to orient themselves before being asked for feedback. A 5-10 second delay is a good default.

Page targeting

Show the widget only on pages that match a URL pattern. Combine with different question text per page to ask context-aware questions.

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: {
      pattern: "/pricing*"       // Only show on pricing pages
    },
    text: {
      question: "Finding what you need?",
      negativePrompt: "What's unclear about our pricing?"
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>

Pattern syntax

/pricing*pricing page and subpages
/checkout/*all checkout flow pages
/blog/*/commentsblog comment sections
/*all pages (default)
Multiple widgets, different pages: Create separate widgets in your dashboard, each with its own page pattern and question text. Include all widget IDs in a single script tag. FeedbackBar automatically shows the most specific match per page.
<script src="https://cdn.feedbackbar.io/widget.js" data-widget="wgt_pricing, wgt_checkout, wgt_global"></script>

Programmatic trigger

The most powerful option. Call FeedbackBar.open() from any JavaScript event: a button click, scroll threshold, exit intent, form abandonment, or anything else you can detect. The widget opens its feedback modal immediately.

Basic usage

// Open the feedback modal programmatically
window.FeedbackBar.open();

This opens the modal for whichever widget is currently active on the page. It works whether the widget bar is visible or hidden.

Attach to a button

<button onclick="FeedbackBar.open()">
  Was this helpful?
</button>

Runtime configuration overrides

Override any widget setting at runtime using window.FeedbackBarConfig. This lets you change the question text, colors, position, and behavior per page without creating separate widgets in the dashboard.

Override priority

Settings merge with the following priority (highest wins):

  1. FeedbackBarConfig (client-side overrides)
  2. Dashboard settings (server-side configuration)
  3. Default values

Full override example

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",

    // Override brand colors
    theme: {
      primaryColor: "#1E40AF",
      textColor: "#FFFFFF",
      borderRadius: 12
    },

    // Override position
    position: {
      placement: "bottom-left",
      offsetX: 20,
      offsetY: 20
    },

    // Override question text per page
    text: {
      question: "How's the checkout experience?",
      positivePrompt: "Glad to hear! What went well?",
      negativePrompt: "What almost stopped you?",
      thankYouMessage: "Thanks, we read every response."
    },

    // Override behavior
    behavior: {
      showAfterSeconds: 15,
      hideAfterDismiss: true,
      showOnMobile: true,
      collectRating: true,
      collectEmail: false,
      pattern: "/checkout/*"
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>

You only need to include the properties you want to override. Everything else uses your dashboard settings.

Recipes: real-world triggers

Copy-paste these patterns. Each one targets a specific moment of friction where users are most likely to share useful feedback.

Conversion

Pricing page exit intent

Ask what's holding them back when the cursor moves toward the browser tab (desktop only).

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: { pattern: "/pricing*", showAfterSeconds: 0 },
    text: {
      question: "Finding what you need?",
      negativePrompt: "What's holding you back from signing up?"
    }
  };

  // Trigger on exit intent (cursor leaves viewport)
  document.addEventListener('mouseout', function(e) {
    if (e.clientY < 10) {
      window.FeedbackBar.open();
    }
  }, { once: true });
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>
Churn prevention

Checkout: time-on-page frustration

If someone has been on checkout for 60+ seconds without completing, something is likely wrong.

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: { pattern: "/checkout*", showAfterSeconds: 60 },
    text: {
      question: "Having trouble?",
      negativePrompt: "What's getting in the way of completing your purchase?"
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>
Onboarding

Post-signup: what almost stopped you

Ask immediately after successful signup to capture friction signals while memory is fresh.

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: { pattern: "/welcome*", showAfterSeconds: 3 },
    text: {
      question: "You made it! Quick question:",
      positivePrompt: "What convinced you to sign up?",
      negativePrompt: "What almost stopped you from signing up?"
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>
Content

Article: scroll depth (80%+)

Only ask users who actually read the content. Ignore bouncers.

<script>
  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    behavior: { pattern: "/blog/*", showAfterSeconds: 0 },
    text: {
      question: "Was this article helpful?",
      negativePrompt: "What was missing or unclear?"
    }
  };

  // Trigger at 80% scroll depth
  let triggered = false;
  window.addEventListener('scroll', function() {
    if (triggered) return;
    const scrollPct = (window.scrollY + window.innerHeight) /
                      document.documentElement.scrollHeight;
    if (scrollPct > 0.8) {
      triggered = true;
      window.FeedbackBar.open();
    }
  });
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>
Support

After support ticket close

Trigger from your app logic when a ticket is marked resolved.

// In your app code, after resolving a ticket:
function onTicketResolved() {
  // Open feedback with support-specific context
  window.FeedbackBar.open();
}

// FeedbackBarConfig set elsewhere with:
// text: {
//   question: "Was your issue resolved?",
//   negativePrompt: "What's still not working?"
// }
Optimization

A/B test question wording

Test different question framings to see which gets more responses or more detailed comments.

<script>
  const variant = Math.random() > 0.5 ? 'direct' : 'empathetic';

  window.FeedbackBarConfig = {
    widgetId: "your-widget-id",
    text: {
      question: variant === 'direct'
        ? "Was this page helpful?"
        : "Did you find what you were looking for?",
      negativePrompt: variant === 'direct'
        ? "What would make it better?"
        : "What were you hoping to find?"
    }
  };
</script>
<script src="https://cdn.feedbackbar.io/widget.js"></script>

Best practices

Do

  • • Ask one question per trigger. Keep it focused
  • • Match the question to the page context
  • • Use once: true on event listeners to avoid repeat triggers
  • • Give users 5-10 seconds to orient before asking
  • • Use hideAfterDismiss: true to respect "no"

Avoid

  • • Triggering immediately on page load (feels intrusive)
  • • Showing on every single page (feedback fatigue)
  • • Generic questions like "Rate your experience" (unhelpful responses)
  • • Triggering multiple times per session without once
  • • Blocking the user's primary task with a modal
The golden rule:Ask when the user has just experienced something, good or bad. That's when they have an opinion and the context to articulate it. A feedback prompt 10 seconds after a confusing interaction gets 10x better responses than a persistent button they walk past every day.

Single-page app support

FeedbackBar automatically detects client-side navigation (pushState, replaceState, popstate). When the URL changes, the widget re-evaluates which pattern matches and shows or hides accordingly. No extra configuration needed for React, Next.js, Vue, or any SPA framework.

If you have multiple widgets with different patterns, the most specific match always wins. For example, /checkout/payment beats /checkout/* which beats /*.