A web markup and feedback tool for collecting visual feedback from clients and account managers
npm install @sirendesign/markupA powerful web markup and feedback tool for collecting visual feedback from clients and account managers. Similar to marker.io, this tool provides an easy-to-use widget for capturing screenshots, adding annotations, and managing feedback items.
Multi-tenant feedback with authentication and real-time sync! See FIREBASE_SETUP.md for complete setup instructions.
- 🔒 User Authentication - Email/password authentication via Firebase
- ☁️ Cloud Storage - Feedback stored in Firestore with real-time sync
- 🏢 Multi-Tenancy - Each website/project has isolated feedback
- 🔄 Real-time Updates - Changes sync instantly across all devices
- 👥 User Tracking - Know who submitted each ticket
- 📸 Screenshot Capture - Capture viewport screenshots with one click
- ✏️ Annotation Tools - Add arrows, rectangles, circles, highlights, text, and freehand drawings
- ✂️ Copy Amendments - Click on text to suggest changes with before/after comparison
- 📋 Session Activity Timeline - Records user interactions (clicks, navigation, scrolls, inputs) during the session
- 🎨 Design Mockup Overlay - Upload mockups and overlay them on the live site for pixel-perfect comparison
- 🔍 Component Detection - Automatically identifies React components and HTML elements
- 💬 Feedback Management - Create, view, and manage feedback items
- 🏷️ Tags & Priority - Organize feedback with custom tags and priority levels (Low, Medium, High, Critical)
- 📊 Status Tracking - Track feedback status (Open, In Progress, Resolved, Closed)
- 👥 Role-Based Permissions - Edit/Delete restricted to developers and feedback creators
- 💾 Local or Cloud Storage - Works offline or with Firebase sync
- 🔌 API Integration - Optional API endpoint for server-side storage
- ⌨️ Keyboard Shortcuts - Quick access with customizable shortcuts
- 🎨 Customizable - Theming, labels, and position options
``bash`
npm install @siren/markup firebaseor
yarn add @siren/markup firebaseor
pnpm add @siren/markup firebase
Note: firebase is included as a peer dependency if you want to use authentication and cloud sync.
`tsx
import { MarkupWidget } from '@siren/markup';
import '@siren/markup/dist/styles.css';
function App() {
return (
$3
`tsx
import { MarkupWidget, initFirebase } from '@siren/markup';
import '@siren/markup/dist/styles.css';// 1. Create .env in YOUR app (not the npm package):
// VITE_FIREBASE_API_KEY=...
// VITE_FIREBASE_AUTH_DOMAIN=...
// etc.
// 2. YOUR app reads .env and calls initFirebase once
initFirebase({
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
});
function App() {
return (
);
}
`With Firebase enabled:
- ✅ Users must sign in to submit feedback
- ✅ Feedback syncs across devices in real-time
- ✅ Each
projectId has isolated feedback
- ✅ Track who submitted each ticketSee FIREBASE_SETUP.md for complete setup instructions.
$3
For Next.js 13+ with the App Router, create a client component:
`tsx
// components/FeedbackWidget.tsx
'use client';import { MarkupWidget } from '@siren/markup';
import '@siren/markup/dist/styles.css';
export default function FeedbackWidget() {
return (
config={{
projectId: 'my-project',
id: 'user-123',
name: 'John Doe',
email: 'john@example.com',
},
}}
/>
);
}
`Then use it in your layout:
`tsx
// app/layout.tsx
import FeedbackWidget from '@/components/FeedbackWidget';export default function RootLayout({ children }) {
return (
{children}
);
}
`Configuration Options
`typescript
interface MarkupConfig {
// Required: Project identifier
projectId: string;
// User information (optional)
user?: {
id: string;
name: string;
email: string;
avatar?: string;
role?: 'admin' | 'developer' | 'client' | 'account-manager';
};
// API endpoint for storing feedback (uses local storage if not provided)
apiEndpoint?: string;
// API key for authentication
apiKey?: string;
// Widget position (default: 'bottom-right')
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
// Primary color (default: '#6366f1')
primaryColor?: string;
// Whether widget opens by default
defaultOpen?: boolean;
// Keyboard shortcut (default: 'ctrl+shift+m')
shortcut?: string;
// Custom labels
labels?: {
widgetButton?: string;
feedbackTitle?: string;
submitButton?: string;
cancelButton?: string;
};
// Callback when feedback is submitted
onSubmit?: (feedback: FeedbackItem) => void | Promise;
// Callback when status changes
onStatusChange?: (feedbackId: string, status: FeedbackStatus) => void | Promise;
// Tags available for feedback
availableTags?: string[];
// Team members for assignment
teamMembers?: UserInfo[];
}
`API Integration
To store feedback on your server, provide an
apiEndpoint:`tsx
config={{
projectId: 'my-project',
apiEndpoint: 'https://api.yourserver.com',
apiKey: 'your-api-key',
onSubmit: async (feedback) => {
// Custom handling after submission
console.log('Feedback submitted:', feedback);
},
}}
/>
`$3
If you provide an
apiEndpoint, implement these endpoints:-
GET /projects/:projectId/feedback - List all feedback
- POST /projects/:projectId/feedback - Create feedback
- PATCH /projects/:projectId/feedback/:id - Update feedback
- DELETE /projects/:projectId/feedback/:id - Delete feedback
- POST /projects/:projectId/feedback/:id/comments - Add comment
- POST /projects/:projectId/upload - Upload screenshot (returns { url: string })Using the Store Directly
Access the feedback store for custom integrations:
`tsx
import { useMarkupStore } from '@company/markup';function AdminDashboard() {
const { feedbackItems, updateFeedbackItem } = useMarkupStore();
const openItems = feedbackItems.filter(item => item.status === 'open');
return (
Open Feedback ({openItems.length})
{openItems.map(item => (
{item.title}
))}
);
}
`Customization
$3
Override CSS variables for custom theming:
`css
.markup-widget {
--markup-primary: #your-brand-color;
--markup-primary-hover: #your-brand-color-darker;
--markup-bg: #ffffff;
--markup-bg-secondary: #f3f4f6;
--markup-border: #e5e7eb;
--markup-text: #1f2937;
--markup-text-secondary: #6b7280;
--markup-radius: 12px;
}
`$3
`tsx
config={{
projectId: 'my-project',
labels: {
widgetButton: 'Report Issue',
feedbackTitle: 'Submit Feedback',
submitButton: 'Send',
cancelButton: 'Close',
},
}}
/>
`Advanced Features
$3
The widget automatically tracks user interactions during their session, including:
- Clicks - Element details, text content, HTML structure
- Navigation - URL changes and page visits
- Scrolling - Scroll position changes
- Input Events - Form interactions (values are masked for privacy)
When viewing feedback, click "Play Session" to see a chronological timeline of these actions, helping developers understand the user's journey before reporting an issue.
$3
Upload a design mockup image and overlay it on the live site to compare:
1. Click "Upload Design Mockup" when creating feedback
2. Select your design file (PNG, JPG, SVG)
3. View the feedback and toggle the overlay with opacity slider
4. Perfect for pixel-perfect QA and design review
$3
The tool automatically identifies:
- React component names (from
data-component or React Fiber)
- HTML element structure (tag, id, classes)
- Text content of clicked elementsThis information is attached to copy amendment feedback to help developers locate exact elements in code.
Development
`bash
Build the package
npm run buildWatch mode for development
npm run devType check
npm run type-checkRun tests
npm testRun tests with coverage
npm run test:coverage
`Testing
Comprehensive test suite for all environments:
`bash
Run all tests
npm testRun specific test suites
npm run test:unit # Unit tests
npm run test:integration # PHP integration tests
npm run test:coverage # With coverage reportTest PHP environment locally
npm run test:php # Starts PHP server on :8080Run all environment tests
./scripts/test-all.shPre-publish validation
./scripts/pre-publish.sh
`See TESTING.md for detailed testing documentation.
$3
A complete PHP test environment is included:
`bash
cd php-test
php -S localhost:8080
`Then open http://localhost:8080 to test the widget in a PHP environment.
See php-test/README.md for details.
Production Deployment
Before deploying to production:
1. Run validation:
npm run validate
2. Build: npm run build
3. Test all environments: ./scripts/test-all.sh
4. Review: PRODUCTION_CHECKLIST.md
5. Publish: npm publish --access publicSee PRODUCTION_CHECKLIST.md for the complete deployment checklist.
CDN Usage
For non-React/PHP environments, use the standalone bundle:
`html
``See CDN_SETUP.md and PHP_INTEGRATION.md for details.
- CDN Setup Guide - Deploy to CDN for PHP/non-React sites
- PHP Integration - Using the widget in PHP applications
- Firebase Setup - Cloud storage and authentication
- User Profiles - User management and roles
- Testing Guide - Comprehensive testing documentation
- Production Checklist - Pre-deployment validation
MIT