Docs

Install Feedinbox

Feedinbox is two features on one script: a feedback widget (a floating button) and Why-Not-Buy (a one-question card that fires when a visitor abandons your pricing or checkout). You add one script, then fire two events for the Why-Not-Buy part.

Overview

  1. Add the script to your site (once). This powers both features.
  2. For Why-Not-Buy, fire a high_intent event when a visitor shows buying intent, and a converted event when they purchase.
  3. Turn each feature on or off from your dashboard. No redeploy needed.
The feedback widget needs only the script. Why-Not-Buy needs the script and the two event calls, because the card only fires when you signal intent.

1. Add the script

Paste this before the closing </body> tag on your site. Replace YOUR_PROJECT_KEY with your key from Dashboard → Project → Settings → Project Key.

Any site
<!-- Add before </body> -->
<script>window.feedinbox=window.feedinbox||function(){(window.feedinbox.q=window.feedinbox.q||[]).push(arguments)}</script>
<script async src="https://feedinbox.com/widget.js" data-project-key="YOUR_PROJECT_KEY"></script>

Framework snippets

Next.js (App Router):

app/layout.tsx
import Script from 'next/script'

// Add to your app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        {/* Queue stub so events fired before the widget loads aren't lost */}
        <Script id="feedinbox-stub" strategy="beforeInteractive">
          {`window.feedinbox=window.feedinbox||function(){(window.feedinbox.q=window.feedinbox.q||[]).push(arguments)}`}
        </Script>
        <Script
          src="https://feedinbox.com/widget.js"
          data-project-key="YOUR_PROJECT_KEY"
          strategy="lazyOnload"
        />
      </body>
    </html>
  )
}

// Then, from your pricing/checkout code, fire high-intent events:
//   window.feedinbox('event', 'high_intent', { plan: 'pro' }) // e.g. pricing modal opened
//   window.feedinbox('event', 'converted')                    // on successful purchase

React (Vite / CRA):

public/index.html
<!-- Add to your public/index.html before </body> -->
<script>window.feedinbox=window.feedinbox||function(){(window.feedinbox.q=window.feedinbox.q||[]).push(arguments)}</script>
<script async src="https://feedinbox.com/widget.js" data-project-key="YOUR_PROJECT_KEY"></script>

<!-- Then fire high-intent events from your pricing/checkout code:
     window.feedinbox('event', 'high_intent', { plan: 'pro' })  // pricing modal opened
     window.feedinbox('event', 'converted')                     // on successful purchase -->
No-code platforms: use the platform's custom-code slot. Webflow: Project Settings → Custom Code → Footer. Shopify: theme.liquid before </body>. Framer: Site Settings → Custom Code → End of <body>. Google Tag Manager: a Custom HTML tag firing on all pages. The stub line matters: it queues events fired before the script finishes loading.

2. Fire the events (Why-Not-Buy)

From your own pricing / checkout code, tell Feedinbox when a visitor shows intent and when they convert:

Your pricing / checkout code
// Fire when a visitor reaches a buying surface
// (opens your pricing modal, starts checkout, clicks "Upgrade")
window.feedinbox('event', 'high_intent', { plan: 'pro' })

// Fire when they actually buy. This cancels the pending question,
// so people who purchased are never asked.
window.feedinbox('event', 'converted')
  • Event names must match your dashboard config. Defaults are high_intent and converted (Pro can rename them).
  • The context object is optional metadata (e.g. { plan: 'pro' }). It's shown tagged on each response.
  • If converted fires within the configured delay, the card is cancelled. This is why firing it accurately matters: it stops you asking buyers.

Where to fire them

Fire high_intent at the exact moment of intent. A React example:

PricingButton.jsx
function PricingButton() {
  const openPricing = () => {
    setPricingOpen(true)
    // tell Feedinbox this is a high-intent moment
    window.feedinbox('event', 'high_intent', { plan: 'pro' })
  }
  return <button onClick={openPricing}>See pricing</button>
}

Fire converted on your success step (payment confirmed, thank-you page):

success handler
// On your payment-success / thank-you step
window.feedinbox('event', 'converted')
Good high_intent moments: pricing modal opens, pricing page loads, checkout starts, "Upgrade" clicked. Good converted moments: payment success callback, subscription-created webhook echoed to the client, thank-you page.

Feature combinations

You wantFeedback buttonWhy-Not-BuyEvent calls?
Why-Not-Buy onlyOffOnYes
Feedback onlyOnOffNo
BothOnOnYes

Toggle the feedback button in Widget editor and Why-Not-Buy in the Why-Not-Buy tab → Configure. Both toggles are free.

How the card behaves

  • The card appears the configured number of seconds after high_intent, only if converted hasn't fired.
  • Once a visitor answers, they aren't asked again for the rest of that session.
  • Responses land in your dashboard (Why-Not-Buy tab), tagged by plan and country, plus a weekly summary email.

Troubleshooting

  • Card never appears: confirm Why-Not-Buy is enabled, your high_intent event name matches the dashboard, and that converted isn't firing too early.
  • Buyers get asked: your converted event isn't firing. Fire it on the real success step.
  • Nothing loads: check the project key and that the script tag is on the page. Keep the stub line so early events aren't dropped.

Install with your AI agent

Using Cursor, Claude Code, or another AI assistant? Point it at our machine-readable guide and it can add Feedinbox for you:

Prompt for your AI assistant
Read https://feedinbox.com/llms.txt and add Feedinbox Why-Not-Buy to my pricing page. My project key is YOUR_PROJECT_KEY.

The guide at /llms.txt is a complete, plain-text version of this page written for AI agents.