PHPackages                             twisted-binary/laravel-feedback-widget - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. twisted-binary/laravel-feedback-widget

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

twisted-binary/laravel-feedback-widget
======================================

AI-powered feedback widget for Laravel + Inertia + Vue apps that creates GitHub issues.

1.5.0(1mo ago)0643↓33.3%MITPHPPHP ^8.4CI failing

Since Feb 20Pushed 2mo agoCompare

[ Source](https://github.com/twisted-binary/laravel-feedback-widget)[ Packagist](https://packagist.org/packages/twisted-binary/laravel-feedback-widget)[ RSS](/packages/twisted-binary-laravel-feedback-widget/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (14)Versions (14)Used By (0)

Laravel Feedback Widget
=======================

[](#laravel-feedback-widget)

An AI-powered feedback widget for Laravel + Inertia + Vue apps. Users describe bugs, feature requests, or general feedback through a guided chat — the AI structures it into a well-formatted GitHub issue automatically.

Features
--------

[](#features)

- **Guided chat** — AI asks follow-up questions to gather the right details for each feedback type (bug, feature, feedback)
- **Auto-structured issues** — Produces well-formatted GitHub issues with proper sections (Steps to Reproduce, Expected Behavior, etc.)
- **Screenshot uploads** — Users can paste or attach screenshots for bug reports
- **Star ratings** — Optional 5-star rating for general feedback
- **GitHub App auth** — Uses GitHub App installation tokens (not PATs) for secure issue creation
- **Zero config UI** — Drop `` into any layout; routes, bindings, and Inertia props are handled by the service provider
- **AI cost tracking** — Per-request token usage logged to a `feedback_ai_costs` table with conversation-level grouping

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

[](#requirements)

- PHP 8.4+
- Laravel 12+
- Inertia.js v2 (Vue 3)
- An OpenAI API key
- A GitHub App with issue write permissions

Installation
------------

[](#installation)

### 1. Composer

[](#1-composer)

```
composer require twisted-binary/laravel-feedback-widget
```

### 2. Vite config

[](#2-vite-config)

The Vue components ship as raw SFCs inside the Composer package. Add a resolve alias so Vite can find them:

```
import path from 'node:path';

export default defineConfig({
    resolve: {
        alias: {
            '@twisted-binary/feedback-widget': path.resolve(
                'vendor/twisted-binary/laravel-feedback-widget/resources/js/index.ts',
            ),
        },
    },
    // ...
});
```

### 3. Publish config (optional)

[](#3-publish-config-optional)

```
php artisan vendor:publish --tag=feedback-widget-config
```

This publishes `config/feedback-widget.php` where you can customize routes, middleware, throttling, and more.

### 4. Publish and run migrations (optional)

[](#4-publish-and-run-migrations-optional)

AI cost tracking is enabled by default. To create the `feedback_ai_costs` table:

```
php artisan vendor:publish --tag=feedback-widget-migrations
php artisan migrate
```

To disable cost tracking entirely, set `FEEDBACK_WIDGET_TRACK_AI_COSTS=false` in your `.env`.

OpenAI API Setup
----------------

[](#openai-api-setup)

This package uses the OpenAI API to power the guided feedback chat. Here's how to get set up:

### 1. Create an OpenAI account

[](#1-create-an-openai-account)

Go to [platform.openai.com](https://platform.openai.com/) and sign up or log in.

### 2. Add billing

[](#2-add-billing)

Navigate to **Settings** → **Billing** and add a payment method. The API is pay-per-use — the default `gpt-4o-mini` model is very affordable for short feedback conversations.

### 3. Generate an API key

[](#3-generate-an-api-key)

Go to **API keys** ([platform.openai.com/api-keys](https://platform.openai.com/api-keys)) → **Create new secret key**.

Give it a name (e.g. `feedback-widget`) and copy the key — you won't be able to see it again.

### 4. Add to your `.env`

[](#4-add-to-your-env)

```
OPENAI_API_KEY=sk-...
OPENAI_FEEDBACK_MODEL=gpt-4o-mini    # optional, defaults to gpt-4o-mini
```

The `OPENAI_FEEDBACK_MODEL` setting is optional. `gpt-4o-mini` is the default and works well for feedback conversations. You can switch to `gpt-4o` for higher quality responses at a higher cost.

GitHub App Setup
----------------

[](#github-app-setup)

This package uses a GitHub App (not a personal access token) to create issues. Here's how to set one up:

### 1. Create the GitHub App

[](#1-create-the-github-app)

Go to [github.com/settings/apps/new](https://github.com/settings/apps/new) and configure:

FieldValueApp nameSomething like `myapp-feedback`Homepage URLYour app URLWebhookUncheck "Active" (not needed)Permissions → Repository → IssuesRead &amp; writeWhere can this app be installed?Only on this accountClick **Create GitHub App**. Note the **App ID** shown on the next page.

### 2. Generate a private key

[](#2-generate-a-private-key)

On the app settings page, scroll to **Private keys** → **Generate a private key**. A `.pem` file downloads.

### 3. Install the app on your repo

[](#3-install-the-app-on-your-repo)

On the app settings page, click **Install App** in the left sidebar → **Install** on your account → select **Only select repositories** → pick your feedback repo → **Install**.

Note the **Installation ID** from the URL after installing:

```
https://github.com/settings/installations/INSTALLATION_ID

```

### 4. Base64-encode the private key

[](#4-base64-encode-the-private-key)

```
cat your-app.private-key.pem | base64 | tr -d '\n'
```

Copy the output — you'll use it as `GITHUB_APP_PRIVATE_KEY` below.

Environment Variables
---------------------

[](#environment-variables)

Add these to your `.env`:

```
# OpenAI
OPENAI_API_KEY=sk-...
OPENAI_FEEDBACK_MODEL=gpt-4o-mini    # optional, defaults to gpt-4o-mini

# GitHub App
GITHUB_APP_ID=123456
GITHUB_APP_PRIVATE_KEY=base64:...     # base64-encoded PEM private key
GITHUB_APP_INSTALLATION_ID=789
GITHUB_REPO_OWNER=your-org
GITHUB_REPO_NAME=your-repo
GITHUB_FEEDBACK_LABEL=user-feedback   # optional

# Widget
FEEDBACK_WIDGET_APP_NAME=MyApp        # optional, used in AI prompts
FEEDBACK_WIDGET_ROUTE_PREFIX=feedback  # optional
FEEDBACK_WIDGET_LOCALE=en             # optional, defaults to app()->getLocale()
FEEDBACK_WIDGET_TRACK_AI_COSTS=true   # optional, defaults to true
```

Usage
-----

[](#usage)

Add the widget to your layout:

```

import { FeedbackWidget } from '@twisted-binary/feedback-widget';

```

**Note:** The widget uses a singleton pattern — only one instance per page is supported.

That's it. The service provider automatically:

- Registers routes (`POST /feedback/chat`, `POST /feedback/issue`)
- Binds the chat and issue services
- Shares route URLs to the frontend via Inertia props

Configuration
-------------

[](#configuration)

The full config file (`config/feedback-widget.php`):

```
return [
    'route_prefix' => env('FEEDBACK_WIDGET_ROUTE_PREFIX', 'feedback'),
    'middleware' => ['web', 'auth', 'verified'],
    'throttle' => [
        'chat' => '30,1',   // 30 requests per minute
        'issue' => '5,1',   // 5 requests per minute
    ],
    'openai_model' => env('OPENAI_FEEDBACK_MODEL', 'gpt-4o-mini'),
    'github' => [
        'app_id' => env('GITHUB_APP_ID'),
        'private_key' => env('GITHUB_APP_PRIVATE_KEY'),
        'installation_id' => env('GITHUB_APP_INSTALLATION_ID'),
        'repo_owner' => env('GITHUB_REPO_OWNER'),
        'repo_name' => env('GITHUB_REPO_NAME'),
        'feedback_label' => env('GITHUB_FEEDBACK_LABEL', 'user-feedback'),
    ],
    'screenshot_disk' => 'public',
    'screenshot_path' => 'feedback-screenshots',
    'app_name' => env('FEEDBACK_WIDGET_APP_NAME', env('APP_NAME', 'the application')),
    'locale' => env('FEEDBACK_WIDGET_LOCALE', null), // null = app()->getLocale()
    'track_ai_costs' => env('FEEDBACK_WIDGET_TRACK_AI_COSTS', true),
];
```

Multilanguage Support
---------------------

[](#multilanguage-support)

### AI Response Language (`locale`)

[](#ai-response-language-locale)

Set `FEEDBACK_WIDGET_LOCALE` in your `.env` to control the language the AI responds in. When not set, it falls back to `app()->getLocale()`. For English (`en`), no extra instruction is prepended to the AI prompt.

#### Per-user locale

[](#per-user-locale)

Leave `FEEDBACK_WIDGET_LOCALE` unset and the widget will automatically use whatever locale your app has set for the current request. If you already set the locale per user via middleware (e.g. `app()->setLocale($user->locale)`), the AI will respond in that user's language with no extra configuration.

### UI Translations (`translations` prop)

[](#ui-translations-translations-prop)

All UI strings have English defaults. To translate the widget, pass a `translations` prop with your overrides:

```

import { FeedbackWidget } from '@twisted-binary/feedback-widget';
import type { FeedbackTranslations } from '@twisted-binary/feedback-widget';

const translations: Partial = {
    header: 'Envoyer un commentaire',
    bugLabel: 'Bug',
    featureLabel: 'Fonctionnalité',
    feedbackLabel: 'Avis',
    inputPlaceholder: 'Tapez votre message...',
    successMessage: 'Merci pour votre retour !',
    // ... override only the strings you need
};

```

You only need to pass the strings you want to override — all others fall back to the English defaults. See the `FeedbackTranslations` interface for the full list of translatable strings.

Exports
-------

[](#exports)

The package exports:

```
import { FeedbackWidget, FeedbackChatPanel, useFeedbackChat } from '@twisted-binary/feedback-widget';
import { defaultTranslations } from '@twisted-binary/feedback-widget';
import type { FeedbackTranslations } from '@twisted-binary/feedback-widget';
```

ExportDescription`FeedbackWidget`Full widget with FAB button + chat panel (drop into layout)`FeedbackChatPanel`Chat panel only (if you want a custom trigger)`useFeedbackChat`Composable with all state and methods`defaultTranslations`Default English translations object`FeedbackTranslations`TypeScript interface for all translatable stringsAI Cost Tracking
----------------

[](#ai-cost-tracking)

Every chat request logs token usage (prompt tokens, completion tokens, model) to the `feedback_ai_costs` table. Each conversation is grouped by a UUID `conversation_id` so you can aggregate usage per feedback session.

Query examples:

```
use TwistedBinary\FeedbackWidget\Models\FeedbackAiCost;

// Total tokens for a conversation
FeedbackAiCost::forConversation($id)->sum('total_tokens');

// All costs for a user
FeedbackAiCost::forUser($userId)->get();

// Daily token usage
FeedbackAiCost::whereDate('created_at', today())->sum('total_tokens');
```

To disable, set `track_ai_costs` to `false` in your config or `.env`. No rows will be inserted and the migration is still publishable but optional.

How It Works
------------

[](#how-it-works)

1. User clicks the floating action button
2. Selects feedback type (bug / feature / feedback)
3. Chats with the AI assistant which guides them through the details
4. AI produces a structured title + body and asks for confirmation
5. On confirmation, a GitHub issue is created with proper labels
6. User sees a success state

License
-------

[](#license)

MIT

###  Health Score

46

—

FairBetter than 93% of packages

Maintenance88

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

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 ~3 days

Recently: every ~8 days

Total

13

Last Release

52d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/6096583?v=4)[Tiago Basilio Silva](/maintainers/tmbs88)[@tmbs88](https://github.com/tmbs88)

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/twisted-binary-laravel-feedback-widget/health.svg)

```
[![Health](https://phpackages.com/badges/twisted-binary-laravel-feedback-widget/health.svg)](https://phpackages.com/packages/twisted-binary-laravel-feedback-widget)
```

###  Alternatives

[wireui/wireui

TallStack components

1.8k1.3M16](/packages/wireui-wireui)[livewire/volt

An elegantly crafted functional API for Laravel Livewire.

4205.3M84](/packages/livewire-volt)[ramonrietdijk/livewire-tables

Dynamic tables for models with Laravel Livewire

21147.4k](/packages/ramonrietdijk-livewire-tables)[emargareten/inertia-modal

Inertia Modal is a Laravel package that lets you implement backend-driven modal dialogs for Inertia apps.

88103.7k](/packages/emargareten-inertia-modal)

PHPackages © 2026

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