PHPackages                             arhx/improveme - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. arhx/improveme

ActiveLibrary[Testing &amp; Quality](/categories/testing)

arhx/improveme
==============

Drop-in feedback &amp; bug-report widget for Laravel. A floating bug icon lets users describe an issue or suggestion, visually pick the related DOM block (drill-down picker), and ships the report (HTML, selector, screenshot) to Telegram and/or a log file.

v1.3.0(1mo ago)093↑50%MITPHPPHP ^8.2

Since Jun 6Pushed 1mo agoCompare

[ Source](https://github.com/arhx/improveme)[ Packagist](https://packagist.org/packages/arhx/improveme)[ Docs](https://github.com/arhx/improveme)[ RSS](/packages/arhx-improveme/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (11)Versions (9)Used By (0)

improveme
=========

[](#improveme)

A drop-in **feedback &amp; bug-report widget** for Laravel. It adds a floating 🐞 icon to your site; clicking it lets a user write a bug report or a suggestion, visually **pick the related block on the page** (with a drill-down picker that lets you "see through" to the element behind), and ships the report — its text, a CSS selector, the element's HTML and a **screenshot of the area** — to **Telegram** and/or a **log file**.

- Zero front-end build step — the widget is plain JS served by a route.
- Works out of the box: with no Telegram config it just logs to a file.
- Auto-injects into your pages, or place it manually with `@improveme`.
- Fully publishable config; rename the env vars; override the route/controller.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, 12 or 13

Install
-------

[](#install)

```
composer require arhx/improveme
```

That's it. The service provider is auto-discovered and, by default, the widget **auto-injects** before `` on every HTML page. Open any page and you'll see the floating icon in the bottom-right corner.

> Reports are written to `storage/logs/improveme.log` immediately, even before you configure Telegram.

Configure Telegram (optional)
-----------------------------

[](#configure-telegram-optional)

Add to your `.env`:

```
IMPROVEME_TELEGRAM_TOKEN=123456:ABC-your-bot-token
IMPROVEME_TELEGRAM_CHAT_ID=-1001234567890
```

Now every report is sent to that chat (screenshot as a photo with the report as caption). Leave them unset and only the log channel runs.

To send into a forum topic: `IMPROVEME_TELEGRAM_THREAD_ID=42`.

File GitHub issues (optional)
-----------------------------

[](#file-github-issues-optional)

Turn each report into a GitHub issue in your repo's tracker — handy when you want feedback to land somewhere an AI coding agent (or a human) can read and act on directly:

```
IMPROVEME_GITHUB_ENABLED=true
IMPROVEME_GITHUB_TOKEN=ghp_your_token        # PAT with issues:write
IMPROVEME_GITHUB_REPO=owner/repo
```

Use a classic PAT with the `repo` scope, or a fine-grained PAT scoped to **Issues: Read and write** on the target repo. Each issue gets the report's message as title, the page URL, picked selector/HTML, browser console errors and a screenshot reference in the body, labelled `improveme` + `bug`/`enhancement`(missing labels are created automatically). Channels stack — Telegram and GitHub can both be on at once. Configure labels/endpoint in the published config.

Inertia (Vue / React) projects
------------------------------

[](#inertia-vue--react-projects)

improveme works out of the box in Laravel + Inertia apps — no Inertia dependency is added to your project. A few notes on how it fits an SPA:

- **One injection, survives navigation.** The snippet is injected once into the initial full-page HTML (your root template, e.g. `app.blade.php`, which contains ``) and attaches to `` — outside Inertia's app root — so the widget stays put across client-side visits. Inertia's partial XHR responses (carrying the `X-Inertia` header) and any AJAX/JSON responses are never touched.
- **Fresh CSRF token.** In an SPA the page never reloads, so a token captured at first paint can go stale once the server-side session regenerates (a login via Fortify/Sanctum, say). The widget therefore reads Laravel's `XSRF-TOKEN` cookie at send-time — the same approach axios uses — and only falls back to the inline token when no cookie is present. This avoids spurious `419 TokenMismatch` errors on long-lived sessions. Override the cookie name with `IMPROVEME_XSRF_COOKIE` if you have customised it.
- **JSON in, JSON out.** The report endpoint always responds with JSON (a `200 {ok:true}`, or `422 {ok:false, errors}` on validation failure) — never a redirect or a flash message — so it composes cleanly with `HandleInertiaRequests` and your shared props without interfering with them.

Nothing extra to configure: `composer require arhx/improveme` and the widget shows up. Restrict it to staging/authenticated users with the env switches below.

Manual placement
----------------

[](#manual-placement)

Prefer to control exactly where the snippet renders? Turn off auto-injection and drop the directive in your layout:

```
IMPROVEME_INJECT=false
```

```

  ...
  @improveme

```

Common env switches
-------------------

[](#common-env-switches)

EnvDefaultMeaning`IMPROVEME_ENABLED``true`Master on/off switch.`IMPROVEME_INJECT``true`Auto-inject before ``.`IMPROVEME_AUDIENCE``all``all` | `auth` | `guest`.`IMPROVEME_POSITION``bottom-right`Icon corner.`IMPROVEME_ACCENT``#ff5a36`Icon / primary button colour.`IMPROVEME_HOVER_COLOR``#3b82f6`Element hover outline.`IMPROVEME_SELECTED_COLOR``#22c55e`Picked element outline.`IMPROVEME_SCREENSHOT_PADDING``15`Px captured around the selection.`IMPROVEME_XSRF_COOKIE``XSRF-TOKEN`Cookie read for a fresh CSRF token (SPA/Inertia).`IMPROVEME_TELEGRAM_TOKEN`—Bot token (enables Telegram).`IMPROVEME_TELEGRAM_CHAT_ID`—Target chat id.`IMPROVEME_GITHUB_ENABLED``false`File a GitHub issue per report.`IMPROVEME_GITHUB_TOKEN`—PAT with `issues:write`.`IMPROVEME_GITHUB_REPO`—Target repo as `owner/repo`.Publish &amp; customise
-----------------------

[](#publish--customise)

Publish the config to tweak anything (and to rename the env vars — just edit the `env('…')` calls in the published file):

```
php artisan vendor:publish --tag=improveme-config
```

Publish the Blade snippet (e.g. to restyle the bootstrap):

```
php artisan vendor:publish --tag=improveme-views
```

Self-host the JS asset instead of serving it from a route:

```
php artisan vendor:publish --tag=improveme-assets
```

### Override the route or controller

[](#override-the-route-or-controller)

Point the package at your own controller (extend the bundled one for the easiest path):

```
// config/improveme.php
'controller' => \App\Http\Controllers\MyReportController::class,
```

```
use Arhx\Improveme\Http\Controllers\ReportController;

class MyReportController extends ReportController
{
    protected function rules(array $config): array
    {
        return array_merge(parent::rules($config), [
            'message' => ['required', 'string', 'min:10', 'max:5000'],
        ]);
    }
}
```

Or take over routing entirely:

```
// config/improveme.php
'register_routes' => false,
```

```
// routes/web.php
Route::post('feedback', \App\Http\Controllers\MyReportController::class);
```

How the picker works
--------------------

[](#how-the-picker-works)

1. Click 🎯 **Pick an element** — the page enters picking mode.
2. Hovering outlines the block under the cursor (hover colour).
3. Click to select it (selected colour). The selection stays highlighted.
4. Hovering the selected block now **sees through it** — the outline previews the block *behind* it; clicking again drills to that containing block.
5. Press **Esc** (or **Done**) to finish. A screenshot of the selection (padded by 15px) is captured client-side via [html2canvas-pro](https://github.com/yorickshan/html2canvas-pro) — a maintained html2canvas fork that understands Tailwind 4's `oklch()` colours (lazy-loaded from a CDN; URL configurable via `IMPROVEME_HTML2CANVAS_URL`).

The report payload includes a unique CSS selector, the element's `outerHTML`(truncated), its bounding rect, the page URL/title, viewport, user agent, the request IP, the authenticated user id (just `Auth::id()` — no name/email), any buffered browser **console errors**, and the screenshot.

Console/JS errors are captured from the moment the widget snippet is parsed: `console.error(...)`, uncaught `error` events (including failed resource loads) and `unhandledrejection` are buffered (last 50) and attached automatically — so a bug report comes with the relevant console output already in it.

What gets sent
--------------

[](#what-gets-sent)

```
{
  "type": "bug",                  // or "idea"
  "message": "…",
  "page":   { "url": "…", "title": "…", "referrer": "…" },
  "viewport": { "w": 1440, "h": 900, "dpr": 2 },
  "userAgent": "…",
  "element": { "selector": "…", "tag": "div", "html": "…", "rect": {…} },
  "consoleErrors": [ { "level": "error", "text": "TypeError: …" } ],
  "screenshot": "data:image/png;base64,…"
}
```

The server additionally records the request **IP** and the authenticated **user id** (resolved from `Auth::id()`) — these are taken server-side, not from the payload.

License
-------

[](#license)

MIT © arhx

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance92

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

8

Last Release

40d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c469eedd85ea02524e6a49abc5f3e28c3d1a373aebf5b1c8b3ae324a501d1910?d=identicon)[Arhangelx](/maintainers/Arhangelx)

---

Top Contributors

[![arhx](https://avatars.githubusercontent.com/u/50137702?v=4)](https://github.com/arhx "arhx (8 commits)")

---

Tags

laravelqascreenshotwidgettelegramfeedbackbug-report

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/arhx-improveme/health.svg)

```
[![Health](https://phpackages.com/badges/arhx-improveme/health.svg)](https://phpackages.com/packages/arhx-improveme)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k55.4M9.2k](/packages/larastan-larastan)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15118.7k4](/packages/calebdw-larastan)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
