@mifort-solutions/report-issue
In-page Ctrl+Q bug reporter for React 19 apps — a custom right-click menu that opens a text report, a Lightshot-style screenshot annotator, a screen recorder, or an "About this page" panel, with a browser/OS/environment block auto-appended to every report.
Framework-agnostic (no Next.js coupling): panels lazy-load via React.lazy, and every app-specific
concern (submit endpoint, build identity, upload limits, analytics) is injected through a required
config prop — the package ships no app-specific defaults.
Install
npm install @mifort-solutions/report-issuePeer deps: react and react-dom ^19. The package brings its own lucide-react, html2canvas,
clsx, and tailwind-merge.
Usage
import { ReportIssue } from '@mifort-solutions/report-issue';
<ReportIssue
config={{
submitEndpoint: '/api/report', // where the multipart report is POSTed
appVersion: '1.2.3', // shown in the environment block / About panel
appCommit: 'abc1234', // short SHA, or '' when unavailable
uploadLimits: {
maxFiles: 5,
maxFileBytes: 10 * 1024 * 1024,
maxTotalBytes: 25 * 1024 * 1024,
acceptedTypes: ['image/png', 'image/jpeg', 'application/pdf'],
acceptHint: '.png, .jpg, .pdf',
},
onTrack: (action, params) => {}, // analytics sink — pass a no-op to disable
}}
/>;config is required; omitting it (or any field) is a type error. Mount it once, near the root,
so the Ctrl+Q shortcut is available on every page.
Next.js (App Router) — Server Component layouts
onTrack is a function, which cannot cross the Server→Client boundary as a prop. Mount the
widget through a thin client wrapper:
// app/ReportIssueMount.tsx
'use client';
import { ReportIssue } from '@mifort-solutions/report-issue';
// …import your analytics + config…
export function ReportIssueMount() {
return <ReportIssue config={{ /* … */ }} />;
}…then render <ReportIssueMount /> from your Server Component layout.tsx.
Styling — required Tailwind tokens (peer requirement)
The package ships Tailwind class strings, not CSS. Your app's Tailwind build must (1) scan the package and (2) define the design tokens below, or the widget renders unstyled.
1. Add the package to your content globs:
// tailwind.config.ts
content: [
'./src/**/*.{js,ts,jsx,tsx,mdx}',
'./node_modules/@mifort-solutions/report-issue/dist/**/*.{js,mjs}',
];2. Define these tokens in theme.extend (colors / shadow / radius):
| Token | Used for |
|---|---|
brand (+ 50, dark) |
accent, CTAs, indicator dot |
ink (+ muted, soft) |
text |
line |
borders / dividers |
surface |
muted backgrounds |
shadow-card-hover |
dialog / menu elevation |
rounded-btn |
button radius |
(Standard Tailwind utilities — red-600, gray-300, etc. — are used as-is.)
What it sends
submitReport POSTs multipart/form-data to config.submitEndpoint:
| field | notes |
|---|---|
message |
description + appended environment block |
url |
page URL |
selector, elementText, email |
optional |
files |
screenshot / recording / attachments |
Your endpoint owns validation, storage, and notifications, and should return { ok: boolean, message?: string }. The package is backend-agnostic.
Notes
- Lazy-loaded: visitors who never open report mode download none of the panel code or
html2canvas— each panel is a separate chunk fetched on first use. - SSR-safe: the widget is
'use client'and guards everywindow/navigatoraccess. - The report UI carries
data-report-ui(excluded from screenshots) andmifort-widget="ReportIssue".
License
MIT