Wirebug

Wirebug is a drop-in feedback widget for Laravel. It captures the technical context of a bug report automatically, optionally records the user's screen through native browser APIs, and stores everything in your own database.
Installation
composer require edulazaro/wirebug
php artisan migrate
The migration is registered by the package, so there is nothing to publish to run it.
Dependencies worth knowing. The report form renders as a modal from wiremodal (Composer installs it automatically) and every open and close goes through window.Wiremodal. Alpine.js and wiremodal must both be present on the page. If wiremodal's JavaScript is not loaded, clicking the button silently does nothing.
The CSS is not injected for you, and the import order matters: wiremodal first, then wirebug, which builds on top of it.
@import '../../vendor/edulazaro/wiremodal/resources/css/wiremodal.css';
@import '../../vendor/edulazaro/wirebug/resources/css/wirebug.css';
With the order reversed the modal renders unstyled.
Usage
The whole integration surface is one Blade component, usually placed in the logged-in app shell:
<x-wirebug />
Wirebug shares the wire* theme attribute with wiremodal, wiretoast and wirecookies:
<html data-wire-theme="studio">
Trigger styles
The default is a floating square button in a bottom corner. The alternative is an edge tab stuck flush to the side of the screen, which drops its label and shows only the icon on narrow viewports.
<x-wirebug trigger="tab" position="bottom-right" tab-label="Feedback" />
Every visible string is overridable through a prop (title, tab-label and the rest) or you can publish the translations and manage the text in language files.
Screen recording
When the user clicks record, Wirebug uses the browser's native getDisplayMedia and MediaRecorder. No encoding library, and no server involved until the report is sent. Nothing records until that click.
Once recording starts the modal closes and a small in-app overlay takes over with a live timer plus Stop and Discard controls, so the user can reproduce the bug across the app. On stop, the modal reopens with the video already attached.
'recording' => [
'enabled' => true,
'max_seconds' => 90,
'max_kb' => 51200,
'bitrate' => 2000000,
],
Two megabits is plenty to read a UI and keeps a full ninety seconds comfortably under the size limit.
Behaviour to know: the recording lives in the page's JavaScript context, so it survives wire:navigate navigation, and a user can start recording on one screen and keep going as Livewire swaps pages. A hard reload ends it, because the browser discards the JS context.
The record button only appears on desktop browsers that support the API.
What gets stored
Reports live in a wirebug_reports table in your own database. Alongside the message, Wirebug captures the current URL, the user agent, the viewport, the app locale and the referer, with no input from the user. Set the capture_context config flag to false to disable that block.
An optional screenshot goes through Laravel's Storage on whatever disk you configure; the row keeps only the path, so local and S3-compatible disks behave identically.
Reading reports back
use EduLazaro\WireBug\Models\BugReport;
BugReport::new()->latest()->get(); // fresh reports, status 'new'
BugReport::ofType('bug')->get();
$report->reporter; // the User, Client... or null for a guest
reporter is a polymorphic relation, so a triage screen is a few queries and no extra schema.
Careful with the type keys. They are
bug,ideaandother, and the middle one is labelled "Suggestion" in the UI. Filtering for suggestions isBugReport::ofType('idea'), notofType('suggestion').
Front-end hook
Wirebug dispatches a wirebug-sent event on window after a successful send.
built and maintained by Edu Lazaro · MIT license