In-App Feedback
Let users report bugs and request features from inside your app — recording their screen and voice, annotating a screenshot, and submitting it in one flow. Captures land on your dashboard Feedback board, where Gemini has already transcribed the narration and drafted a title, type, priority and summary.
Everything here uses a public key (pk_*), safe for the browser.
The drop-in widget
The fastest path is the <simplr-feedback> web component from @simplr-ai/web-components — it works in any framework or plain HTML.
<script src="https://cdn.jsdelivr.net/npm/@simplr-ai/web-components/dist/simplr-web-components.global.js"></script>
<script>
SimplrWebComponents.SimplrElements.configure({
apiKey: "pk_live_xxx",
rum: { applicationId: "my-app" }, // optional; links the report to the RUM session
user: { id: currentUser.id, email: currentUser.email, name: currentUser.name },
});
SimplrWebComponents.defineSimplrElements();
</script>
<simplr-feedback position="bottom-right"></simplr-feedback>
That renders a floating button. When opened, the user can:
- Record screen + voice —
getDisplayMedia+ microphone, mixed into one recording. - Screenshot + annotate — capture a frame and draw with pen / arrow / box / highlight.
- Pick a type — bug, feature, question, other — add an optional title/description, and submit.
- Stay identified — signed-in users are attached automatically; otherwise the widget asks for an email so received, in-progress, testable, and release updates can be delivered.
position accepts bottom-right (default), bottom-left, top-right, top-left. Listen for completion:
window.addEventListener("simplr-feedback-submitted", (e) => console.log("sent", e.detail.id));
For apps where the user signs in after the SDK is configured, identify them when the session becomes available:
SimplrWebComponents.SimplrElements.identify({
id: currentUser.id,
email: currentUser.email,
name: currentUser.name,
});
React hook
Prefer to build your own trigger UI? Use useSimplrFeedback from @simplr-ai/js/react.
import { useSimplrFeedback } from "@simplr-ai/js/react";
function ReportButton() {
const fb = useSimplrFeedback({ apiKey: "pk_live_xxx", applicationId: "my-app" });
async function report() {
await fb.startRecording({ microphone: true });
// user narrates while using the app…
const recording = await fb.stopRecording();
await fb.submit({ type: "bug", title: "Checkout 404", attachments: recording ? [recording] : [] });
}
return <button onClick={report}>{fb.isRecording ? "Stop recording" : "Report a bug"}</button>;
}
The hook exposes isRecording, isSubmitting, progress, error, plus startRecording, stopRecording, cancelRecording, captureScreenshot, and submit.
Programmatic client
For full control, use the SimplrFeedback class and the capture helpers directly.
import { SimplrFeedback, ScreenRecorder, captureScreenshot, CanvasAnnotator } from "@simplr-ai/js";
const client = new SimplrFeedback({
apiKey: "pk_live_xxx",
applicationId: "my-app",
user: { id: currentUser.id, email: currentUser.email, name: currentUser.name },
});
const shot = await captureScreenshot();
await client.submit({
type: "feature",
title: "Add dark mode",
attachments: [{ kind: "screenshot", blob: shot.blob, mimeType: "image/png", width: shot.width, height: shot.height }],
});
submit() accepts an onProgress(fraction) callback so you can show upload progress.
Call client.identify(user) when the signed-in user changes. Your application user id is stored as an external reference; it is not treated as a Simplr portal user id.
How uploads work
submit() never streams large files through your server:
- It
POSTs the item to/v1/feedbackwith the attachment list. - The API returns a short-lived signed upload URL per attachment.
- The SDK
PUTs each blob directly to storage, then calls the complete endpoint. - Once all uploads finish, AI enrichment (transcription + drafting) runs automatically.
Privacy
By default the widget strips the query string from the captured page URL (redactUrl: true) and only sends benign device context (user agent, viewport, language, timezone). Recordings and screenshots are stored privately and only ever served to your dashboard through short-lived signed URLs.
Reference
| Endpoint | Auth | Purpose |
|---|---|---|
POST /v1/feedback | pk_* | Create an item; returns signed upload URLs |
POST /v1/feedback/:id/attachments/:attId/complete | pk_* | Confirm an upload finished |