Install · Ruby on Rails
Bug reports and feedback from your Ruby on Rails site, in one script tag.
Where it goes
In app/views/layouts/application.html.erb, just before the closing body tag.
Setup
Adding the widget to Ruby on Rails
- 01
Copy your widget key
From the Widget tab of your project in UserWants. The key starts with uw_pk_ and is public by design: it is rendered into every page you serve, and the domain allowlist rather than secrecy is what makes it safe to expose.
- 02
Add the tag to your application layout
One edit covers every controller and view that renders through the default layout. Use javascript_include_tag with a full URL so the asset pipeline treats it as remote and leaves it alone.
erb<%# app/views/layouts/application.html.erb %> <%= yield %> <script src="https://userwants.app/widget.js" data-userwants-key="<%= Rails.application.credentials.userwants_key %>" defer ></script> </body> - 03
Identify the current user
If you have a current_user helper, pass the id you already have and the reporter is never asked for an email. Rendering it as JSON from the layout keeps it in one place rather than scattered through views.
erb<% if current_user %> <script> window.UserWants?.identify(<%= raw({ identifier: current_user.id.to_s, name: current_user.name, email: current_user.email }.to_json) %>); </script> <% end %> - 04
Allow your domain
Add your production hostname under Allowed domains in the Widget tab. The list fails closed, so until the domain is there the widget only runs on localhost — which also means a staging host needs its own entry.
Worth knowing
What bites on Ruby on Rails
Turbo caches the page, and that is fine
Turbo Drive swaps the body on navigation, but the widget mounts its own element and re-attaches rather than disappearing. You do not need a turbo:load listener, and adding one that re-initialises will be ignored.
content_security_policy needs two entries
If you use the Rails CSP initializer, add https://userwants.app to both policy.script_src and policy.connect_src. Missing connect_src produces a widget that opens and then cannot submit.
Do not vendor the file into app/assets
Copying widget.js into Sprockets or Propshaft pins you to whatever version you copied, so every later fix passes you by, and it serves the file from your own origin for no benefit. Load it from the CDN and let it update itself.
ActionCable and background jobs are unrelated
The widget talks to its own API directly from the browser. It opens no socket to your app, enqueues nothing, and adds no request to your Puma workers, so it cannot affect your response times under load.
FAQ
Questions
- Is there a Rails gem for the feedback widget?
- No. Nothing runs on your server, so there is no gem, no initializer and no migration. The only Rails code involved is the layout snippet that passes current_user, and even that is optional.
- Does it work with Turbo and Hotwire?
- Yes. Turbo replaces the body on navigation, and the widget re-attaches itself rather than being lost. Each Turbo visit is also recorded as a step, so a report shows which pages preceded the problem.
The full reference — every field the widget collects, the domain allowlist rules and the JavaScript API — is in the widget docs.
Try it on your Ruby on Rails site.
Paste the tag, add your domain, and the next report arrives with the screenshot and the JavaScript error already attached.