AI-powered feedback widget with intelligent triage, drag & drop positioning, and multi-language support.
- AI Triage - Auto-categorization, priority & sentiment analysis
- Duplicate Detection - AI-powered detection of similar feedbacks
- Vision AI - Analyzes attached screenshots
- Auto-Response - Generates helpful AI responses
- Smart Routing - Auto-assigns to teams (dev/design/support)
- i18n - Multi-language support (EN, ES, PT-BR, ZH)
- Drag & Drop - Reposition widget anywhere on screen
- Security - Rate limiting, encryption, input validation
The widget can be dragged and repositioned anywhere on the screen for optimal user experience.
- Node.js 20+
- Docker (for PostgreSQL)
# 1. Clone
git clone https://github.com/yourusername/react_feedback_widget.git
cd react_feedback_widget
# 2. Start backend (PostgreSQL + API)
./start.sh
# 3. Start frontend (new terminal)
cd web && npm install && npm run dev
# Access the application:
# - Frontend: http://localhost:4321
# - API Docs: http://localhost:3333/docs# 1. Clone
git clone https://github.com/yourusername/react_feedback_widget.git
cd react_feedback_widget
# 2. Start PostgreSQL
docker run -d --name feedback-db \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=feedback_widget \
-p 5432:5432 postgres:16-alpine
# 3. Setup & start backend
cd api
cp .env.example .env
npm install
npx prisma migrate dev
npm run dev
# 4. Setup & start frontend (new terminal)
cd web
cp .env.example .env
npm install
npm run dev
# Open http://localhost:4321The widget works great without AI. To enable:
AI_PROVIDER=ANTHROPIC
AI_API_KEY=sk-your-key
AI_MODEL=claude-sonnet-4-20250514See api/README.md#ai-features-optional for detailed AI configuration and features.
├── api/ # Backend (Express + Prisma)
│ ├── src/
│ │ ├── domain/ # Business logic
│ │ ├── application/ # Use cases
│ │ ├── infrastructure/ # DB, AI, security
│ │ └── presentation/ # Controllers
│ └── prisma/ # Database schema
│
├── web/ # Frontend (Astro + React)
│ ├── src/
│ │ ├── components/ # Widget, AI, Admin
│ │ ├── hooks/ # Reusable logic
│ │ └── lib/ # Crypto, i18n, store
│ └── public/
│
├── mobile/ # Mobile app (React Native + Expo)
│ ├── src/
│ │ ├── components/ # UI components
│ │ ├── hooks/ # Custom hooks
│ │ ├── screens/ # App screens
│ │ └── services/ # API clients
│ └── App.tsx
│
└── docs/ # Documentation
See web/README.md for web frontend architecture details.
See mobile/README.md for mobile app documentation.
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| POST | /feedbacks |
Create feedback |
| GET | /feedbacks |
List feedbacks |
| GET | /feedbacks/stats |
Statistics |
| POST | /ai/analyze |
Analyze text |
| GET | /ai/config |
Get AI config |
| PUT | /ai/config |
Update AI config |
Interactive API documentation is automatically available when the backend is running:
- Development: http://localhost:3333/docs
- Production:
https://your-domain.com/docs
Powered by Scalar with features:
- Interactive API explorer
- Request/response examples
- Built-in test client
- OpenAPI schema download
- Backend: Node.js 20+, Express 5, PostgreSQL 16, Prisma 7
- Frontend: Astro 5, React 19, Tailwind CSS 4
- AI: Anthropic Claude, Moonshot Kimi
- Security: AES-256-GCM, Rate limiting, Zod validation
./start.sh up # Start all services
./start.sh down # Stop all services
./start.sh logs # View logs
./start.sh reset # Reset database (WARNING: deletes data!)
./start.sh migrate # Run migrations
./start.sh studio # Open Prisma Studio (DB GUI)For VPS, EC2, DigitalOcean, etc.
# 1. Setup
./start.sh
# 2. Configure environment
cp .env.production.example .env.production
nano .env.production
# 3. Deploy
docker-compose -f docker-compose.prod.yml --env-file .env.production up -dRequired changes in .env.production:
POSTGRES_PASSWORD=your-strong-password
DATABASE_URL=postgresql://postgres:your-password@postgres:5432/feedback_widget
CORS_ORIGIN=https://yourdomain.comOptional - Enable AI:
AI_PROVIDER=ANTHROPIC
AI_API_KEY=sk-your-keycd api
railway login
railway init
railway add --database postgres
railway upSet environment variables in Railway dashboard:
DATABASE_URL=${{Postgres.DATABASE_URL}}
PORT=3333
CORS_ORIGIN=https://your-frontend.vercel.appcd web
vercelSet environment variable:
PUBLIC_API_URL=https://your-api.up.railway.app# Docker Self-Hosted
git pull
docker-compose -f docker-compose.prod.yml up -d
# Railway
cd api && git pull && railway up
# Vercel
cd web && git pull && vercel --prod| Issue | Solution |
|---|---|
| CORS Errors | Add your frontend domain to API CORS settings |
| Database Connection Failed | Check DATABASE_URL format, verify database is running with docker-compose ps, check logs with docker-compose logs postgres |
| AI Not Working | Verify AI_PROVIDER and AI_API_KEY, test connection in admin dashboard |
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
ENCRYPTION_KEY |
Yes | 64-char hex key for encryption |
PORT |
No | Default: 3333 |
CORS_ORIGIN |
No | Allowed frontend domains |
AI_PROVIDER |
No | ANTHROPIC, MOONSHOT, or NONE |
AI_API_KEY |
No | Your AI provider API key |
| Variable | Required | Description |
|---|---|---|
PUBLIC_API_URL |
Yes | Backend API URL |
PUBLIC_DEFAULT_LANGUAGE |
No | en, es, pt-BR, zh |
PUBLIC_WIDGET_POSITION |
No | bottom-right, bottom-left, etc. |
PUBLIC_WIDGET_COLOR |
No | Brand color (hex without #) |
Supported languages: English, Spanish, Portuguese (BR), Chinese
Add translation in web/src/lib/i18n/locales/:
'widget.new_key': 'Your text',Use in component:
import { t } from "../lib/i18n";
const text = t("widget.new_key", language);# Backend tests
cd api && npm test
# Frontend tests
cd web && npm testThank you for your interest in contributing!
- Fork and clone the repository
- Follow the Quick Start above
- Create a branch:
git checkout -b feature/your-feature-name
- TypeScript: Strict mode enabled
- Naming: PascalCase for components, camelCase for functions
- No
anytypes: Use proper TypeScript types
Follow conventional commits:
feat: add new feature
fix: resolve bug
refactor: improve code structure
docs: update documentation
- Ensure tests pass locally
- Update documentation if needed
- Link related issues
- Request review
- Never commit
.envfiles - Sanitize user inputs
- Use parameterized queries
When adding UI text:
-
Add to all translation files:
web/src/lib/i18n/locales/en.tsweb/src/lib/i18n/locales/es.tsweb/src/lib/i18n/locales/pt-BR.tsweb/src/lib/i18n/locales/zh.ts
-
Use the translation key:
import { t } from "../lib/i18n"; const text = t("your.key", language);
We follow Clean Architecture principles with clear dependency direction:
┌─────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ (Controllers, Components, Routes) │
├─────────────────────────────────────────────────────────────┤
│ APPLICATION LAYER │
│ (Use Cases / Application Services) │
├─────────────────────────────────────────────────────────────┤
│ DOMAIN LAYER │
│ (Entities, Value Objects, Repository Interfaces) │
├─────────────────────────────────────────────────────────────┤
│ INFRASTRUCTURE LAYER │
│ (Database, External APIs, Email, Encryption, AI) │
└─────────────────────────────────────────────────────────────┘
Dependency Rule: Dependencies only point inward. Domain has no external dependencies.
- Repository Pattern: Decouple domain logic from database implementation
- Use Cases: Isolate business operations from HTTP/UI concerns
- Dependency Injection: Enable testing and loose coupling
- Client-Side Encryption: API keys are encrypted in browser, never touch server
| Threat | Mitigation |
|---|---|
| SQL Injection | Prisma ORM (parameterized queries) |
| XSS | No dangerous innerHTML, safe components |
| CSRF | Stateless API, CORS whitelist |
| Rate limiting | IP-based limiting (memory-based, use Redis in prod) |
| API key exposure | Client-side encryption, never logged |
| Screenshot abuse | 5MB size limit, base64 validation |
- API README - Backend documentation & AI features
- Web README - Frontend documentation & Clean Architecture
MIT License - see LICENSE file.
Built for the open source community

