Install · Laravel
Bug reports and feedback from your Laravel site, in one script tag.
Where it goes
In your base Blade layout, usually resources/views/layouts/app.blade.php, just before the closing body tag.
Setup
Adding the widget to Laravel
- 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 HTML that every visitor receives, and the domain allowlist is the control, not keeping the value private.
- 02
Add the tag to your Blade layout
Every view that extends your base layout gets the widget from one edit. Keep it out of individual views so a new page cannot forget it.
blade{{-- resources/views/layouts/app.blade.php --}} @yield('content') <script src="{{ config('services.userwants.script') }}" data-userwants-key="@php echo config('services.userwants.key') @endphp" defer ></script> </body> - 03
Put the key in config, not in the view
Add it to config/services.php and read it from the environment. The key is public, so this is not about secrecy — it is so staging and production can point at different projects without editing a Blade file.
php// config/services.php 'userwants' => [ 'script' => 'https://userwants.app/widget.js', 'key' => env('USERWANTS_KEY'), ], - 04
Identify the authenticated user and allow your domain
Laravel already knows who is signed in, so passing the id costs one Blade directive and means nobody is asked for an email. Then add your production hostname under Allowed domains in the Widget tab; the list fails closed.
blade@auth <script> window.UserWants?.identify(@json([ 'identifier' => (string) auth()->id(), 'name' => auth()->user()->name, 'email' => auth()->user()->email, ])); </script> @endauth
Worth knowing
What bites on Laravel
Vite and Mix are not involved
Do not import the widget in resources/js or add it to your Vite input array. There is no module to bundle — it is a remote tag, and putting it through your build only means shipping a copy that never updates.
Livewire and Inertia both work unchanged
Neither replaces the document, so the widget attaches once and survives every partial update or Inertia visit. Each navigation is recorded as a step in the report.
A strict CSP needs two directives
If you send a Content-Security-Policy header, allow https://userwants.app in both script-src and connect-src. With only script-src the button renders and then fails when someone submits.
FAQ
Questions
- Is there a Composer package for Laravel?
- No. Nothing runs on your server, so there is no package, no service provider and no migration. The widget is a browser script, and the only Laravel-side code is the Blade snippet that passes the authenticated user.
- Does it capture PHP exceptions from my Laravel app?
- No, only JavaScript errors in the browser. If a request returns a 500 and your app renders an error page, the report carries the description, the screenshot and the URL — pair it with your own log to find the exception.
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 Laravel site.
Paste the tag, add your domain, and the next report arrives with the screenshot and the JavaScript error already attached.