Feedback widget best practices
Keep the button visible but quiet, open a short form instead of a survey, load the script deferred and isolated, identify signed-in users, restrict the key to your domains and rate-limit submissions.
By Rafael Thayto · Last updated
Placement: visible, never in the way
- Put a small floating button in a bottom corner, on the side your chat or cookie banner isn't on.
- Add a contextual entry point where problems happen: "Report a problem" next to an export, "Suggest an improvement" at the end of a flow. Preselect the type so the form opens ready.
- Don't pop the form open on its own. Feedback that customers start themselves is more specific and more honest than feedback you interrupt them for.
With Escuta Produto, data-position moves the button and any element with data-escuta-open="bug" opens the form with the type preselected.
Keep the form short
One open question, a type (bug, idea, praise, other) and an optional rating. Skip required fields you could fill yourself: if the user is signed in, attach their name and email automatically. A long form turns a 20-second report into a chore customers abandon.
Performance
A feedback widget should never cost you speed:
- Load it with
defer(ornext/scriptwithafterInteractive) so it never blocks rendering. - Keep it small and free of dependencies like React or a CSS framework.
- Isolate it in a Shadow DOM so your styles and the widget's styles can't collide.
- Avoid CORS preflights: sending
text/plainsaves a round trip on every submission.
Accessibility
- The trigger is a real
<button>with a text label, not an icon-only div. - The panel is a dialog that closes with Escape and returns focus to the trigger.
- Inputs have labels, and errors are announced in text, not only in color.
- Colors meet contrast on both light and dark sites.
Language
Show the form in the visitor's language. Detect it from the browser and let the site override it (Escuta Produto's data-locale). A Portuguese-speaking customer writes more, and more clearly, in Portuguese.
Spam and abuse
A public form will be found by bots. Layer cheap defenses:
- Allowed origins: only your domains may submit with your key.
- Rate limiting per visitor and product.
- A honeypot field that humans never see; bots fill it and are silently dropped.
- Size limits on the message and metadata.
Privacy
Collect only what helps you act: page, browser, country and the user's identity in your own product. Don't capture keystrokes, screenshots or form contents without asking. Mention the widget in your privacy policy.
How do you know the widget is working?
Watch three numbers in the first month:
- Volume per product. A widget that gets nothing is usually hidden, broken by a Content Security Policy, or loaded on the wrong pages.
- Share of messages with an identified user. If it's low on a logged-in product,
identify()isn't being called. - Type mix. Mostly bugs after a release is normal; mostly "other" means the type buttons aren't clear to your customers.
If volume is low, add a contextual entry point next to your most-used feature before redesigning anything.
Mobile
On phones the floating button competes with bottom navigation bars, cookie banners and chat bubbles. Check it on a real device:
- The button shouldn't cover navigation or the main call to action. Move it to the other side with
data-position="left"if needed. - When the keyboard opens, the message field must stay visible above it.
- Tap targets need to be comfortable for a thumb, not just a mouse pointer.
More detail in Designing a feedback widget for mobile screens.
Test it before customers see it
Before rolling the widget out, walk through it as a customer would:
- Open it with the mouse, then again with only the keyboard (Tab to the button, Enter to open, Escape to close).
- Send one message of each type and confirm each arrives in the inbox with the right page URL.
- Sign in as a test user and check that the email field disappears because
identify()filled it. - Load the page with your Content Security Policy enabled and look for blocked requests in the browser console.
- Check it on a dark page and a light page, on a phone and on a desktop.
Ten minutes of testing catches the problems that otherwise show up as an empty inbox.
What should the button say?
"Feedback" is short and understood in most products. Contextual entry points can be more specific, such as "Report a problem" or "Suggest an improvement", because the customer already knows what they want to say. Keep labels in the customer's language. See What should a feedback button say? for options.
Related
Frequently asked questions
Where should a feedback button be placed on a website?
As a small floating button in a bottom corner that doesn't collide with chat or cookie banners, plus contextual links such as 'Report a problem' next to features where issues happen.
How do you stop spam in a feedback widget?
Combine an allowed-origins list for your public key, rate limiting per visitor, a hidden honeypot field and size limits on the message and metadata.
Will a feedback widget slow down my site?
Not if it loads with defer, has no dependencies, stays small and renders in a Shadow DOM. Escuta Produto's widget is about 5 KB compressed and follows all four rules.
Related
- What should a feedback button say?How to word a feedback button: verbs or nouns, labels that match each page and feedback type, localized copy, and how to replace the default Feedback button.
- Designing a feedback widget for mobile screensDesigning a feedback widget for phones: thumb reach, keyboard overlap, bottom navigation conflicts and the checks to run on a real device before you ship.
- How to make a feedback widget accessibleMake a feedback widget usable with a keyboard and screen reader: real buttons, dialog semantics, focus return, labels, contrast and known gaps.
- Why embeddable widgets use Shadow DOMWhat Shadow DOM isolates in an embeddable feedback widget, what it leaves open to the host page, how to theme across the boundary, and how to test it.