Open-source feedback widget with AI classification. A drop-in React component that captures user feedback, automatically classifies it using Gemini AI, and stores it in Supabase.
- Floating feedback button - Non-intrusive, appears in corner of screen
- Screenshot support - Paste, drag & drop, or click to attach images
- AI classification - Automatically categorizes feedback (bug/feature/question/billing/praise)
- Feature area detection - AI identifies which part of your product is mentioned
- Priority scoring - P0/P1/P2 based on urgency
- Bot protection - Honeypot field + rate limiting
- Email notifications - Get notified via Resend on new feedback
- Supabase storage - Screenshots stored in Supabase Storage
npm install openfeedbacklayer
# or
pnpm add openfeedbacklayer
# or
yarn add openfeedbacklayer// app/layout.tsx or any layout component
import { FeedbackWidget } from 'openfeedbacklayer'
export default function Layout({ children }) {
return (
<html>
<body>
{children}
<FeedbackWidget />
</body>
</html>
)
}Copy the API route template to your Next.js app:
cp node_modules/openfeedbacklayer/src/api/feedback/route.ts app/api/feedback/route.tsOr create app/api/feedback/route.ts manually - see API Route Template.
Run the migration in your Supabase SQL Editor:
# Copy the migration
cat node_modules/openfeedbacklayer/supabase/migrations/001_create_feedback.sqlOr see Migration SQL.
# .env.local
# Required
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJxxx
# For AI classification
GEMINI_API_KEY=AIzaSyxxx
# Optional: Email notifications
RESEND_API_KEY=re_xxx
FEEDBACK_NOTIFY_EMAIL=you@example.com<FeedbackWidget
apiEndpoint="/api/feedback" // API endpoint (default: /api/feedback)
projectId="my-app" // For multi-project setups
position="bottom-right" // bottom-right | bottom-left | top-right | top-left
primaryColor="#2563eb" // Button color
buttonText="Feedback" // Tooltip text
placeholder="Describe your issue..." // Input placeholder
onSubmit={(data) => {}} // Callback after submit
onError={(error) => {}} // Error callback
/>The AI returns structured data:
{
"title": "Export button not working",
"short_summary": "User reports the export button has no effect when clicked.",
"key_details": ["export button", "no response", "dashboard page"],
"suggested_category": "bug",
"suggested_feature_area": "export",
"suggested_priority": "high",
"steps": ["Go to dashboard", "Click export button"],
"expected": "CSV file should download",
"confidence": 0.95,
"clarifying_questions": []
}bug- Something is brokenfeature- Request for new functionalityquestion- How-to or support querybilling- Payment/subscription issuespraise- Positive feedbackother- Doesn't fit above
high→ P0 - Blocking/urgentmedium→ P1 - Importantlow→ P2 - Nice to have
Free-form string detected by AI, e.g.:
- "export", "upload", "dashboard", "billing", "login", "UI", "performance"
CREATE TABLE feedback (
id UUID PRIMARY KEY,
page_url TEXT NOT NULL,
user_agent TEXT,
project_id TEXT,
message_raw TEXT NOT NULL,
screenshot_url TEXT,
ai_data JSONB,
status TEXT DEFAULT 'new',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);-- Get all bugs by priority
SELECT * FROM feedback
WHERE ai_data->>'suggested_category' = 'bug'
ORDER BY
CASE ai_data->>'suggested_priority'
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
ELSE 3
END;
-- Get feedback by feature area
SELECT * FROM feedback
WHERE ai_data->>'suggested_feature_area' = 'export';
-- Count by category
SELECT
ai_data->>'suggested_category' as category,
COUNT(*) as count
FROM feedback
GROUP BY ai_data->>'suggested_category';- Honeypot field - Hidden input that bots fill, humans don't
- Rate limiting - 10 requests per IP per minute
- Supabase RLS - Enable Row Level Security for access control
- No credentials exposed - All API keys are server-side only
Using Gemini 2.5 Flash Lite:
- ~$0.10 per 1M input tokens
- ~$0.40 per 1M output tokens
- Typical feedback: ~200 tokens = $0.00002 per feedback
- React 18+
- Next.js 13+ (App Router)
- Supabase (PostgreSQL + Storage)
- Google Gemini 2.5 Flash Lite
- Resend (optional, for emails)
MIT
PRs welcome! Please open an issue first to discuss changes.
Made with ❤️ by SCAILE Technologies