Docs

Feedback in

Feedback Surface

BubbleMost responses. Best for open-ended feedback.
EmbedSubtle. Works well in docs and help pages.
BannerHigh visibility. Good for announcements or surveys.
ThumbsMinimal friction. Great for binary feedback.
TriggerZero footprint. Best in forms or settings.

Feedback Surface

5 surface types for collecting feedback on your site. Pick the one that fits your context.

SurfaceBest For
BubblePersistent button that opens a feedback overlay. Most responses.
EmbedEmbeds in your page layout. Works well in docs and help pages.
BannerThin bar that slides in after a delay. High visibility for announcements or surveys.
ThumbsMinimal thumbs up/down. Per-feature tracking with data-context.
TriggerZero footprint. Attach to any existing link or button.

All surface types are available on all plans.

Before you start: Go to Settings → Integrations → Surfaces to configure appearance and copy your API key.


Bubble

A floating action button fixed to the bottom corner of every page. Clicking it opens a feedback overlay with a sentiment row first, optional text field second.

When to use it: General-purpose collection across your whole app. Lowest setup cost, highest response volume.

<script async src="https://app.withcircuit.com/widget.js"
  data-api-key="YOUR_API_KEY"
  data-surface="float">
</script>

Paste before </body> on every page where you want the button to appear.

Float-only options:

AttributeValuesDefaultDescription
data-positionbottom-right | bottom-leftbottom-rightCorner the button anchors to
data-button-textany stringFeedbackLabel on the FAB
data-headlesstrue | falsefalseHides the FAB entirely; use window.CircuitWidget.open() to trigger instead

Embed

Renders a "Was this helpful?" widget directly in the document flow — no floating element. Useful in help articles, feature announcements, or anywhere you want feedback anchored to specific content.

When to use it: Feedback tied to a specific piece of content. Responses are naturally scoped to what the user just read.

Place the element where you want the widget to appear, then load the script:

<div data-circuit-inline
  data-api-key="YOUR_API_KEY"
  data-context="help-article:api-docs"
  data-prompt="Was this helpful?">
</div>
<script async src="https://app.withcircuit.com/widget.js"
  data-api-key="YOUR_API_KEY"
  data-surface="inline">
</script>

Inline-only options (on the element, not the script):

AttributeExampleDescription
data-contexthelp-article:api-docsTags the feedback for per-page filtering in analytics. Use a consistent naming pattern: type:name.
data-promptWas this helpful?The question shown above the emoji row. Defaults to "Was this helpful?"

The widget renders in the light DOM, so your page's CSS applies. Use data-primary-color on the script tag to match your brand.


Banner

A thin banner that slides in from the top or bottom of the viewport after a configurable delay. Dismissed with a close button. Good for catching users at a natural transition — after completing a flow, finishing a tutorial, or reaching the end of a page.

When to use it: Post-flow feedback at a specific moment. The delay lets the user settle before the prompt appears.

<script async src="https://app.withcircuit.com/widget.js"
  data-api-key="YOUR_API_KEY"
  data-surface="bar"
  data-prompt="How was your experience?"
  data-context="flow:checkout-complete"
  data-delay="2000">
</script>

Bar-only options:

AttributeExampleDefaultDescription
data-delay20002000Milliseconds before the bar appears. 0 shows it immediately.
data-promptHow was your experience?How was your experience?Question shown in the bar.
data-contextflow:checkout-completeTags submissions for filtering. Use a consistent pattern: flow:name or page:name.

The bar uses Shadow DOM, so your page styles won't bleed in. Configure colours via the shared appearance options.


Thumbs

Two buttons — thumbs up and thumbs down — that submit immediately with no modal. An optional single-line follow-up appears after tapping. Lowest friction of any surface.

When to use it: Per-feature sentiment tracking. Add one next to a new feature, a dashboard widget, or a specific setting. Use data-context to tell submissions apart in analytics.

Place the element where you want the thumbs to appear:

<span data-circuit-thumbs
  data-api-key="YOUR_API_KEY"
  data-context="feature:dark-mode">
</span>
<script async src="https://app.withcircuit.com/widget.js"
  data-api-key="YOUR_API_KEY"
  data-surface="thumbs">
</script>

Thumbs-only option (on the element):

AttributeExampleDescription
data-contextfeature:dark-modeTags the submission. Use feature:name to track per-feature sentiment over time.

You can place multiple [data-circuit-thumbs] elements on the same page with different data-context values. One script tag covers all of them.

Renders in the light DOM.


Trigger

Zero floating UI. Attach to any existing link, button, or CTA — clicking it opens the full feedback modal. Nothing appears on the page until the user clicks.

When to use it: Settings pages, forms, onboarding flows, or anywhere a floating button would feel out of place. You control the trigger entirely.

<a href="#" data-circuit-page data-api-key="YOUR_API_KEY">Give Feedback</a>
<script async src="https://app.withcircuit.com/widget.js"
  data-api-key="YOUR_API_KEY"
  data-surface="page">
</script>

The element's text content becomes the CTA label. Works on <a>, <button>, or any clickable element. Uses Shadow DOM for the modal itself.

No surface-specific attributes — all configuration comes from the shared options below and the element's own text.


Shared Options

These apply to the <script> tag for all surface types.

AttributeValuesDefaultDescription
data-api-keystringRequired. Your Surface API key from Settings → Integrations → Surfaces.
data-surfacefloat | inline | bar | thumbs | pagefloatWhich surface to render.
data-primary-colorhex#1C1A18Button and accent colour.
data-text-colorhex#FFFFFFButton text colour.
data-themeauto | light | darkautoFollows OS preference when auto.
data-border-radiuse.g. 6px6pxApplied to buttons and the modal.
data-font-familysystem | inter | roboto | opensans | poppinssystemFont used inside the surface.
data-show-brandingtrue | falsetrueShows "Powered by Circuit" in the modal footer.
data-headlesstrue | falsefalseSuppresses the FAB (Float only). Trigger via window.CircuitWidget.open().
data-csp-noncestringPass your CSP nonce if your site uses Content-Security-Policy headers.
data-widget-idstringReference a specific saved widget configuration if you have multiple widgets set up.

JavaScript API

After the script loads, window.CircuitWidget is available:

window.CircuitWidget.open();    // Open the feedback modal
window.CircuitWidget.close();   // Close the modal

// Attach user identity to submissions
window.CircuitWidget.identify({
  email: 'jane@acme.com',
  name: 'Jane Doe',
  plan: 'pro'
});

window.CircuitWidget.reset();   // Clear identity
window.CircuitWidget.destroy(); // Remove the widget and clean up

Identify before the surface loads — if your user data is ready before the script executes, queue the call:

window.CircuitWidget = window.CircuitWidget || { _q: [] };
window.CircuitWidget._q.push(['identify', { email: 'jane@acme.com', plan: 'pro' }]);

Circuit processes the queue when the surface initialises.


Analytics

Surface responses flow into your analytics dashboard. See Surface Analytics for metrics, filtering, and export.


Close the Loop

When you mark a spec as Shipped, Circuit can notify the customers whose feedback drove it. See Working with Specs for the full send flow.

Can't find what you're looking for?

Contact support