@inov-ai/feedback-widget
Version:
Modern React feedback widget with surveys, analytics, and Next.js 15 support. Collect user feedback and run surveys in your SaaS applications.
519 lines (407 loc) • 13.5 kB
Markdown
# @inov-ai/feedback-widget
A modern, customizable React feedback widget with surveys, feedback collection, and analytics. Perfect for SaaS applications with full Next.js 15 support and TypeScript.
## About inov-ai
[inov-ai](https://www.inov-ai.tech/) is a comprehensive feedback collection and analytics platform designed to help businesses gather valuable insights from their users. With advanced analytics, real-time feedback processing, and intelligent survey management, Inov-AI empowers companies to make data-driven decisions and improve their products based on actual user feedback.
**To get started with this widget, you'll need to:**
1. Sign up for a free account at [https://www.inov-ai.tech/](https://www.inov-ai.tech/)
2. Create a new project in your dashboard
3. Get your unique site key
4. Install and configure this widget in your application
## Features
- ✅ **Next.js 15 Compatible** - No CSP issues, SSR-safe, hydration-friendly
- ✅ **TypeScript Support** - Full type safety out of the box
- ✅ **Dual Collection Methods** - Quick feedback + detailed surveys
- ✅ **Smart Path Control** - Show widget only on specific routes
- ✅ **Theme Detection** - Auto-detects light/dark themes or use custom
- ✅ **Highly Customizable** - Colors, positions, triggers, animations
- ✅ **Zero Dependencies** - Only requires React as peer dependency
- ✅ **Mobile Responsive** - Works perfectly on all devices
- ✅ **Real-time Analytics** - Track feedback and survey responses
## Installation
```bash
npm install @inov-ai/feedback-widget
# or
yarn add @inov-ai/feedback-widget
# or
pnpm add @inov-ai/feedback-widget
```
## Quick Start
The simplest way to get started is to add the widget to your app with minimal configuration:
### 1. Basic Setup
```jsx
import { InovaiWidget } from '@inov-ai/feedback-widget';
function App() {
return (
<div>
{/* Your app content */}
<h1>My Amazing SaaS App</h1>
{/* Add the feedback widget */}
<InovaiWidget siteKey="your-site-key" />
</div>
);
}
```
### 2. Complete Example (Recommended)
This is the most common setup that works great for most applications:
```jsx
import { InovaiWidget } from '@inov-ai/feedback-widget';
function App() {
return (
<div>
{/* Your app content */}
<h1>My SaaS Dashboard</h1>
{/* Feedback widget with full configuration */}
<InovaiWidget
siteKey="your-site-key"
primaryColor="#f97316"
fontFamily="Inter, system-ui, -apple-system, sans-serif"
fontSize="16px"
buttonRadius="8px"
position="bottom-right"
buttonText="Feedback"
buttonIcon="💬"
theme="auto"
animation="slide"
trigger="manual"
triggerDelay={0}
surveyFrequency="every-visit"
minimized={false}
feedbackTypes={["Bug", "Feature", "Suggestion", "Question"]}
paths={["/", "/dashboard", "/feedback", "/analytics"]}
onSubmit={(data) => {
console.log('Feedback submitted:', data);
// Integrate with your analytics or logging system
}}
onError={(error) => {
console.error('Widget error:', error);
}}
/>
</div>
);
}
```
### 3. Next.js 15 Setup
```jsx
// app/layout.tsx (App Router) or pages/_app.tsx (Pages Router)
import { InovaiWidget } from '@inov-ai/feedback-widget';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
{/* Add feedback widget to every page */}
<InovaiWidget
siteKey={process.env.NEXT_PUBLIC_FEEDBACK_SITE_KEY}
primaryColor="#f97316"
position="bottom-right"
theme="auto"
paths={["/dashboard", "/app", "/settings"]} // Only show on specific routes
/>
</body>
</html>
);
}
```
## Configuration Options
### Required Props
| Prop | Type | Description |
|------|------|-------------|
| `siteKey` | `string` | Your unique site key from inov-ai dashboard |
### Appearance Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `primaryColor` | `string` | `#f97316` | Main color for buttons and highlights |
| `textColor` | `string` | Auto-detected | Text color (auto-detected from theme) |
| `backgroundColor` | `string` | Auto-detected | Modal background color |
| `theme` | `'light' \| 'dark' \| 'auto' \| 'system'` | `auto` | Color theme preference |
| `fontFamily` | `string` | `'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'` | Font family |
| `fontSize` | `string` | `16px` | Base font size |
| `buttonRadius` | `string` | `8px` | Border radius for buttons |
| `position` | `'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left'` | `bottom-right` | Widget position |
| `buttonText` | `string` | `Feedback` | Text on the trigger button |
| `buttonIcon` | `string` | `''` | Icon/emoji for the button |
| `animation` | `'slide' \| 'fade' \| 'none'` | `slide` | Opening animation |
### Behavior Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `trigger` | `'manual' \| 'auto' \| 'timer' \| 'scroll' \| 'exit'` | `manual` | How the widget opens |
| `triggerDelay` | `number` | `0` | Delay in milliseconds for auto triggers |
| `paths` | `string[]` | `[]` | URL paths where widget should appear (empty = all paths) |
| `surveyFrequency` | `'once' \| 'every-visit' \| 'daily' \| 'weekly'` | `every-visit` | How often to allow feedback |
| `minimized` | `boolean` | `false` | Start in minimized state |
| `feedbackTypes` | `string[]` | `['Feature Request', 'Bug Report', 'Integration', 'Question']` | Available feedback categories |
### Event Props
| Prop | Type | Description |
|------|------|-------------|
| `onOpen` | `() => void` | Called when widget opens |
| `onClose` | `() => void` | Called when widget closes |
| `onSubmit` | `(data: FeedbackSubmission) => void` | Called when feedback is submitted |
| `onError` | `(error: Error) => void` | Called when an error occurs |
## Path Configuration
The `paths` prop allows you to control where the widget appears:
```jsx
// Show on specific pages only
<InovaiWidget
siteKey="your-key"
paths={["/", "/dashboard", "/settings"]}
/>
// Show on all dashboard routes
<InovaiWidget
siteKey="your-key"
paths={["/dashboard*"]}
/>
// Show everywhere (default)
<InovaiWidget
siteKey="your-key"
// paths prop omitted or empty array
/>
```
## Survey Integration
The widget automatically fetches and displays surveys from your inov-ai dashboard. Users can:
1. **Quick Feedback**: Submit general feedback with categories
2. **Surveys**: Answer detailed survey questions when available
## Advanced Examples
### With Custom Styling
```jsx
.fb-widget-button {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
## Advanced Examples
### With Custom Styling
```jsx
<InovaiWidget
siteKey="your-site-key"
primaryColor="#6366f1"
theme="dark"
position="bottom-left"
buttonText="Help Us Improve"
buttonIcon="📝"
customCSS={`
[data-feedback-widget] {
--feedback-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
`}
/>
```
### With Analytics Integration
```jsx
<InovaiWidget
siteKey="your-site-key"
onSubmit={(data) => {
// Send to your analytics
analytics.track('Feedback Submitted', {
category: data.category,
page: data.metadata.page_url,
rating: data.rating
});
// Show success message
toast.success('Thank you for your feedback!');
}}
onError={(error) => {
// Log errors
console.error('Feedback widget error:', error);
Sentry.captureException(error);
}}
/>
```
### Timer-based Trigger
```jsx
<InovaiWidget
siteKey="your-site-key"
trigger="timer"
triggerDelay={30000} // Show after 30 seconds
surveyFrequency="once" // Only show once per user
/>
```
### Path-specific Configuration
```jsx
// Show different configurations on different routes
function App() {
const { pathname } = useLocation();
if (pathname.startsWith('/dashboard')) {
return (
<InovaiWidget
siteKey="your-site-key"
feedbackTypes={["Bug Report", "Feature Request", "Performance Issue"]}
paths={["/dashboard*"]}
/>
);
}
if (pathname === '/') {
return (
<InovaiWidget
siteKey="your-site-key"
feedbackTypes={["General Feedback", "Question"]}
trigger="timer"
triggerDelay={60000}
paths={["/"]}
/>
);
}
return null;
}
```
## TypeScript Support
Full TypeScript support with exported types:
```tsx
import {
InovaiWidget,
FeedbackConfig,
FeedbackSubmission,
Survey
} from '@inov-ai/feedback-widget';
const config: FeedbackConfig = {
siteKey: 'your-site-key',
primaryColor: '#f97316',
theme: 'auto'
};
const handleSubmit = (data: FeedbackSubmission) => {
console.log('Feedback received:', data);
};
function App() {
return <InovaiWidget {...config} onSubmit={handleSubmit} />;
}
```
## Migration from Script Widget
If you're migrating from the script-based widget, here's how the props map:
| Script Attribute | React Prop | Notes |
|-------------------|------------|-------|
| `site_key` | `siteKey` | ✅ Same functionality |
| `data-primary-color` | `primaryColor` | ✅ Same functionality |
| `data-theme` | `theme` | ✅ Same functionality |
| `data-position` | `position` | ✅ Same functionality |
| `data-button-text` | `buttonText` | ✅ Same functionality |
| `data-paths` | `paths` | ✅ Same functionality |
| `data-feedback-types` | `feedbackTypes` | ✅ Same functionality |
| `data-trigger` | `trigger` | ✅ Same functionality |
## Troubleshooting
### Widget not appearing?
1. **Check paths configuration**: Make sure current route is in `paths` array
2. **Verify siteKey**: Ensure your site key is correct
3. **Check browser console**: Look for error messages
### Surveys not loading?
1. **Verify site key**: Must match your inov-ai dashboard
2. **Check active surveys**: Ensure you have active surveys in your dashboard
3. **Network issues**: Check browser network tab for failed requests
### Styling issues?
1. **CSS conflicts**: Use `customCSS` prop to override styles
2. **Theme detection**: Set explicit `theme` if auto-detection fails
3. **Z-index issues**: Widget uses z-index: 999999
## Support
- 📖 **Documentation**: [https://docs.inov-ai.tech](https://docs.inov-ai.tech)
- 💬 **Discord**: [Join our community](https://discord.gg/inov-ai)
- 📧 **Email**: support@inov-ai.tech
- 🐛 **Issues**: [GitHub Issues](https://github.com/godbright/inov-ai-package/issues)
- 🔗 **Repository**: [https://github.com/godbright/inov-ai-package.git](https://github.com/godbright/inov-ai-package.git)
## License
MIT License - see LICENSE file for details.
);
}
```
### useThemeDetection
Detect the current theme:
```jsx
import { useThemeDetection } from '@inov-ai/feedback-widget';
function MyComponent() {
const theme = useThemeDetection(); // 'light' | 'dark'
return <div>Current theme: {theme}</div>;
}
```
## Path Monitoring
Control which pages show the widget:
```jsx
<InovaiWidget
siteKey="your-site-key"
paths={[
'/dashboard/*', // All dashboard pages
'/app/settings', // Specific page
'/blog/*', // All blog pages
]}
/>
```
## Environment Variables
For Next.js projects, use environment variables:
```bash
# .env.local
NEXT_PUBLIC_FEEDBACK_SITE_KEY=your-site-key
```
```jsx
<InovaiWidget
siteKey={process.env.NEXT_PUBLIC_FEEDBACK_SITE_KEY}
/>
```
## Triggers
### Manual (Default)
Widget only opens when user clicks the button or you call `openWidget()`.
### Auto
Widget opens immediately when the page loads.
### Timer
Widget opens after a specified delay:
```jsx
<InovaiWidget
trigger="timer"
triggerDelay={5000} // 5 seconds
/>
```
### Scroll
Widget opens when user scrolls 50% down the page:
```jsx
<InovaiWidget trigger="scroll" />
```
### Exit Intent
Widget opens when user moves mouse towards browser top (exit intent):
```jsx
<InovaiWidget trigger="exit" />
```
## Styling
### CSS Variables
The widget respects CSS custom properties:
```css
:root {
--feedback-primary-color: #f97316;
--feedback-text-color: #111827;
--feedback-background-color: #ffffff;
}
```
### Custom CSS
Add custom styles:
```jsx
<InovaiWidget
customCSS={`
.fb-widget-button {
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
transform: scale(1.1);
}
.fb-widget-modal {
backdrop-filter: blur(10px);
}
`}
/>
```
## TypeScript
Full TypeScript support with exported types:
```typescript
import type {
FeedbackConfig,
FeedbackSubmission,
Survey,
SurveyQuestion
} from '@inov-ai/feedback-widget';
const config: FeedbackConfig = {
siteKey: 'your-site-key',
primaryColor: '#f97316',
// ... other options
};
```
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
## License
MIT License - see [LICENSE](LICENSE) for details.
## Support
- 📧 Email: support@inov-ai.tech
- 📖 Documentation: https://docs.inov-ai.tech
- 🐛 Issues: https://github.com/godbright/inov-ai-package/issues
- 🔗 Repository: https://github.com/godbright/inov-ai-package.git