Feedback Widget

The @inputbuffer/feedback package is a lightweight widget you can drop into any web page — documentation sites, dashboards, API references, or your own app. It sends feedback directly to InputBuffer without any server-side code.

By the end of this guide, you'll have a feedback widget on your page that collects thumbs-up/down votes and optional written comments. Each submission appears automatically in your InputBuffer inbox. No backend required.

Before you start

You need a widget-scoped API token. Widget tokens are safe to embed in client-side code — they can only create inputs, not read or modify your organization's data.

To create one:

  1. Go to Settings → API Tokens in your organization
  2. Click Create token and select the Widget scope
  3. Copy the token — it's shown once

Do not use a full-access API token in the widget. Full-access tokens are rejected by the widget API when sent from a browser. Use a widget-scoped token only.

Feedback submitted through the widget is sent to third-party AI services for classification and search. InputBuffer does not yet scrub content before processing — avoid placing the widget where users are likely to submit personal information, credentials, or production secrets.


Quick start

Add an inline thumbs bar

The simplest way to add feedback. Paste this into your page where you want the bar to appear:

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/bar.js"></script>

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?">
</inputbuffer-feedback>

What you should see: A thumbs up/down bar appears inline where you placed the element. After a user clicks a thumb, a short follow-up form appears so they can add context. Once they submit, the feedback appears in your InputBuffer inbox under Inputs.

If the bar does not appear, check your browser console for errors. A 401 error means your token is missing or is a full-access token instead of a widget-scoped one.

More ways to embed

Once the inline bar is working, two other patterns are available:

Floating bar — pins to the bottom of the viewport, useful for documentation pages:

<script src="https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/bar.js"></script>

<inputbuffer-feedback
  api-key="YOUR_WIDGET_TOKEN"
  label="Was this helpful?"
  placement="fixed">
</inputbuffer-feedback>

Modal triggered by a button — attaches to an existing button, no JavaScript required:

<button id="feedback-btn">Send feedback</button>

<script
  src="https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/modal.js"
  data-api-key="YOUR_WIDGET_TOKEN"
  data-attach-to="#feedback-btn">
</script>

The modal opens when the button is clicked. The feedback appears in your InputBuffer inbox once submitted.


Bundles

Three bundles are available. The quick start examples use bar.js or modal.js — pick the smallest bundle that covers your use case:

BundleSizeWhat it includes
bar.js18 KBThumbs up/down bar with optional follow-up form
modal.js19 KBFull-text feedback modal
widget.js36 KBBoth bar and modal

All bundles are available via CDN:

https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/bar.js
https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/modal.js
https://cdn.jsdelivr.net/npm/@inputbuffer/feedback/dist/widget.js

Or install from npm: npm install @inputbuffer/feedback


Web component reference

Use <inputbuffer-feedback> with bar.js or widget.js.

AttributeDefaultDescription
api-keyrequiredYour widget-scoped token
api-urlOverride the API endpoint
labelText shown next to the thumbs (e.g. "Was this helpful?")
show-labeltrueSet to false to hide the text label
placementinlineinline renders in place; fixed pins to bottom of viewport
modal-titleHeading for the follow-up form
modal-placeholderTextarea placeholder text in the follow-up form
show-title-fieldfalseShow optional title field in the follow-up form
show-email-fieldtrueShow optional email field in the follow-up form
sourceTag submissions with a source string for filtering
user-idAttach a user identifier to reaction submissions
theme-primaryPrimary color (buttons, focus rings)
theme-backgroundBar background color
theme-textText color
theme-selectedSelected thumb button background
theme-selected-colorSelected thumb icon color
inject-stylestrueSet to false to disable automatic CSS injection

Script tag auto-init (data-* attributes)

Add data-api-key to any script tag pointing at modal.js or widget.js and the modal initializes automatically:

AttributeDescription
data-api-keyTriggers auto-init on page load
data-attach-toCSS selector for the element that opens the modal on click
data-api-urlOverride the API endpoint
data-color-schemelight, dark, or auto (default: auto)
data-inject-stylesSet to false to disable automatic CSS injection
data-theme-primaryPrimary color
data-theme-backgroundModal background color
data-theme-textText color
data-theme-selectedSelected sentiment thumb background
data-theme-selected-colorSelected sentiment thumb icon color

Programmatic API

For full control, use the JavaScript API directly.

createBar(config)

Clicking a thumb immediately records a reaction via the reactions API (fire-and-forget). The selected vote is persisted to localStorage for 24 hours and restored on revisit — so users see their previous choice when they return to the page.

import { createBar } from '@inputbuffer/feedback';
// or: const { createBar } = window.InputBufferIO;

const bar = createBar({
  apiKey: 'YOUR_WIDGET_TOKEN',
  label: 'Was this helpful?',
  placement: 'inline',  // or 'fixed'
  colorScheme: 'auto',  // 'light' | 'dark' | 'auto'
  showEmailField: true,
  modalTitle: 'Share your feedback',
  modalPlaceholder: "What's on your mind?",
});

document.getElementById('feedback-slot').appendChild(bar.element);

createBar config options:

OptionDefaultDescription
apiKeyrequiredYour widget-scoped token
apiUrlOverride the API endpoint
labelText shown next to the thumbs
placement'inline''inline' renders in place; 'fixed' pins to bottom of viewport
colorScheme'auto''light', 'dark', or 'auto'
showEmailFieldtrueShow optional email field in the follow-up form
modalTitle'Share your feedback'Heading for the follow-up form
modalPlaceholder"What's on your mind?"Textarea placeholder text in the follow-up form
sourceTag submissions with a source string for filtering
userIdAttach a user identifier to reaction submissions
injectStylestrueSet to false to disable automatic CSS injection
themeTheme object — see Theming

Bar instance methods:

MethodDescription
bar.on('vote', ({ sentiment }) => {})User clicked a thumb
bar.on('open', ({ sentiment }) => {})Follow-up form opened
bar.on('submit', ({ id }) => {})Feedback submitted — id is the InputBuffer input ID
bar.on('close', () => {})Follow-up form closed
bar.on('error', (err) => {})Submission failed
bar.destroy()Remove the bar and clean up listeners

createModal(config)

import { createModal } from '@inputbuffer/feedback';
// or: const { createModal } = window.InputBufferIO;

const modal = createModal({
  apiKey: 'YOUR_WIDGET_TOKEN',
  title: 'Share your feedback',
  placeholder: "What's on your mind?",
  showEmailField: true,
  showSentiment: false,
  colorScheme: 'auto',
});

document.getElementById('my-button').addEventListener('click', () => modal.open());

createModal config options:

OptionDefaultDescription
apiKeyrequiredYour widget-scoped token
apiUrlOverride the API endpoint
attachToCSS selector for an element that opens the modal on click
title'Share your feedback'Modal heading
placeholder"What's on your mind?"Textarea placeholder text
showEmailFieldtrueShow optional email field
showSentimentfalseShow thumbs up/down sentiment selector
colorScheme'auto''light', 'dark', or 'auto'
injectStylestrueSet to false to disable automatic CSS injection
themeTheme object — see Theming

Modal instance methods:

MethodDescription
modal.open(options?)Open the modal, optionally with context — see below
modal.close()Close the modal programmatically
modal.destroy()Clean up and remove all listeners
modal.on('submit', ({ id }) => {})Feedback submitted — id is the InputBuffer input ID
modal.on('close', () => {})Modal closed
modal.on('error', (err) => {})Submission failed

The id returned by the submit event is the InputBuffer input ID for the submitted feedback. You can use it to correlate widget submissions with entries in your inbox or via the REST API.

Pass options to pre-populate the modal or attach feedback to a specific target:

modal.open({
  title: 'Feedback on this page',       // Override modal heading
  sentiment: 'negative',                // Pre-select a thumb ('positive' | 'negative')
  prefill: {
    email: '[email protected]',          // Pre-fill email
    description: 'This section was...',  // Pre-fill textarea
  },
  target: {
    type: 'documentation',
    metadata: {
      page_url: window.location.href,
      section_heading: 'Submit your first input',  // optional
    },
  },
});

Targeting

Targets attach feedback to a specific resource in your product — a documentation page, REST endpoint, or CLI command. This lets you see which specific pages or endpoints have the most issues.

Targets are optional. Without a target, feedback goes into your general inbox. With a target, you can filter and track feedback per resource.

Documentation page

modal.open({
  target: {
    type: 'documentation',
    metadata: {
      page_url: 'https://docs.example.com/getting-started',
      section_heading: 'Authentication',  // optional
      doc_version: 'v2',                  // optional
    },
  },
});

REST API endpoint

modal.open({
  target: {
    type: 'rest_endpoint',
    metadata: {
      method: 'POST',
      path: '/v1/users',
      host: 'api.example.com',   // optional
      api_version: 'v1',         // optional
    },
  },
});

CLI command

modal.open({
  target: {
    type: 'cli_command',
    metadata: {
      command: 'deploy',
      subcommand: 'production',  // optional
      cli_version: '2.4.0',     // optional
      args: ['--env', 'prod'],   // optional
    },
  },
});

Theming

Color scheme

createModal({ apiKey: '...', colorScheme: 'dark' });
// or 'light' | 'auto' (default: 'auto' follows system preference)

Theme object

Override individual colors via the theme config option:

createModal({
  apiKey: '...',
  theme: {
    primary: '#6366f1',       // Button and focus ring color
    background: '#1e1e2e',    // Modal background
    surface: '#2a2a3e',       // Modal header background
    text: '#cdd6f4',          // Body text
    selected: '#6366f1',      // Selected thumb background
    selectedColor: '#ffffff', // Selected thumb icon color
  },
});

The same theme option is available on createBar(). For the web component, use theme-* attributes:

<inputbuffer-feedback
  api-key="..."
  theme-primary="#6366f1"
  theme-background="#1e1e2e"
  theme-text="#cdd6f4">
</inputbuffer-feedback>

CSS custom properties

When injectStyles is true (default), the widget injects its own stylesheet and exposes CSS custom properties you can override:

/* Modal: set on #ib-modal */
#ib-modal {
  --ib-primary: #6366f1;
  --ib-primary-hover: #4338ca;
  --ib-background: #1e1e2e;
  --ib-surface: #2a2a3e;
  --ib-text: #cdd6f4;
  --ib-muted: #9399b2;
  --ib-border: #45475a;
  --ib-selected: #6366f1;
  --ib-selected-color: #ffffff;
  --ib-radius: 8px;
  --ib-radius-input: 4px;
}

/* Bar: set on .ib-bar-wrapper */
.ib-bar-wrapper {
  --ib-primary: #6366f1;
}

CSS customization

When injectStyles: false, you can style everything from scratch using stable selectors.

SelectorElement
#ib-overlayFull-screen backdrop
#ib-modalModal container (CSS variable scope)
#ib-modal-headerHeader bar
#ib-modal-bodyBody content area
#ib-titleModal heading
#ib-textareaFeedback textarea
#ib-emailEmail input
#ib-submitSubmit button
#ib-closeClose button
#ib-successSuccess message
#ib-errorError message

Bar selectors

SelectorElement
.ib-bar-wrapperOuter wrapper (CSS variable scope)
.ib-barVisible bar strip
.ib-bar-labelLabel text
.ib-bar-btnThumb buttons
.ib-popoverFollow-up popover
.ib-popover-headerPopover header
.ib-popover-titlePopover heading
.ib-popover-textareaFeedback textarea
.ib-popover-emailEmail input
.ib-popover-submitSubmit button
.ib-popover-successSuccess message
.ib-popover-errorError message

Next steps

  • REST API reference — submit feedback server-side, query inputs, or integrate with your backend