Skip to content

agilek/react-light-feedback

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-light-feedback

A lightweight, dead-simple React library for capturing in-app user feedback with automatic metadata collection and optional screenshots.

Features

  • Simple integration - Drop in a single component
  • Multiple backends - Supabase, Firebase, or any webhook
  • Automatic metadata - URL, viewport, browser info, timestamps
  • Optional screenshots - Powered by html2canvas
  • Customizable UI - CSS variables for theming
  • TypeScript - Full type definitions included
  • Lightweight - Tree-shakeable, minimal dependencies

Installation

npm install react-light-feedback

Peer Dependencies

For screenshots (optional):

npm install html2canvas

For Supabase provider:

npm install @supabase/supabase-js

For Firebase provider:

npm install firebase

Quick Start

With Supabase

import { FeedbackWidget } from 'react-light-feedback';

function App() {
  return (
    <FeedbackWidget
      provider="supabase"
      supabaseUrl="https://xxx.supabase.co"
      supabaseKey="your-anon-key"
    />
  );
}

With Firebase

import { FeedbackWidget } from 'react-light-feedback';

function App() {
  return (
    <FeedbackWidget
      provider="firebase"
      firebaseConfig={{
        apiKey: "your-api-key",
        projectId: "your-project-id",
        // ... other config
      }}
      collectionName="feedback" // optional, defaults to "feedback"
    />
  );
}

With Webhook

import { FeedbackWidget } from 'react-light-feedback';

function App() {
  return (
    <FeedbackWidget
      provider="webhook"
      webhookUrl="https://your-api.com/feedback"
      webhookHeaders={{ "Authorization": "Bearer token" }} // optional
    />
  );
}

Props

Prop Type Default Description
provider 'supabase' | 'firebase' | 'webhook' Required Backend provider
theme 'light' | 'dark' | 'auto' 'light' Widget theme (auto follows system)
position 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' 'bottom-right' Floating button position
screenshotEnabled boolean true Show screenshot toggle
triggerText string 'Feedback' Button text
modalTitle string 'Send feedback' Modal title
placeholder string "What's on your mind?" Textarea placeholder
user { id?, email?, name? } - User context to include
onSuccess () => void - Called on successful submission
onError (error: Error) => void - Called on submission error
customTrigger React.ReactNode - Replace floating button
disabled boolean false Disable the widget

Supabase-specific props

Prop Type Default Description
supabaseUrl string Required Supabase project URL
supabaseKey string Required Supabase anon key
tableName string 'feedback' Table to insert into

Firebase-specific props

Prop Type Default Description
firebaseConfig object Required Firebase config object
collectionName string 'feedback' Firestore collection

Webhook-specific props

Prop Type Default Description
webhookUrl string Required URL to POST feedback to
webhookHeaders Record<string, string> - Custom headers

Customization

CSS Variables

Override these CSS variables to customize the appearance:

:root {
  --feedback-primary-color: #0066cc;
  --feedback-primary-hover: #0052a3;
  --feedback-bg-color: #ffffff;
  --feedback-text-color: #1a1a1a;
  --feedback-text-secondary: #666666;
  --feedback-border-color: #e0e0e0;
  --feedback-border-radius: 8px;
  --feedback-font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  --feedback-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  --feedback-overlay-bg: rgba(0, 0, 0, 0.5);
}

Custom Trigger

Replace the floating button with your own trigger:

<FeedbackWidget
  provider="supabase"
  supabaseUrl="..."
  supabaseKey="..."
  customTrigger={<button className="my-button">Give Feedback</button>}
/>

Programmatic Usage

Use the useFeedback hook for programmatic control:

import { FeedbackWidget, useFeedback } from 'react-light-feedback';

function MyComponent() {
  const { openModal, submitFeedback, isOpen, isSubmitting } = useFeedback();

  return (
    <button onClick={openModal}>
      Open Feedback Form
    </button>
  );
}

// Wrap your app with FeedbackWidget
function App() {
  return (
    <FeedbackWidget provider="supabase" supabaseUrl="..." supabaseKey="...">
      <MyComponent />
    </FeedbackWidget>
  );
}

Feedback Payload

The payload sent to your backend:

interface FeedbackPayload {
  message: string;
  metadata: {
    pageUrl: string;
    pagePath: string;
    viewport: { width: number; height: number };
    screen: { width: number; height: number };
    userAgent: string;
    timezone: string;
    language: string;
    referrer: string;
    timestamp: string;
  };
  user?: {
    id?: string;
    email?: string;
    name?: string;
  };
  screenshot?: string; // base64 data URL
}

Backend Setup

Supabase Table Schema

create table feedback (
  id uuid default gen_random_uuid() primary key,
  message text not null,
  metadata jsonb not null,
  user_context jsonb,
  screenshot text,
  created_at timestamp with time zone default now()
);

-- Enable RLS
alter table feedback enable row level security;

-- Allow inserts from anon users
create policy "Allow anonymous inserts"
  on feedback for insert
  with check (true);

Firebase Firestore Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /feedback/{document} {
      allow create: if true;
      allow read, update, delete: if false;
    }
  }
}

Webhook Payload

The webhook receives a POST request with Content-Type: application/json and the FeedbackPayload as the body.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published