Widget
The embeddable feedback widget lets your users submit feedback, bug reports, and questions directly from your app. It renders in a Shadow DOM for full style isolation and is under 30KB gzipped.
Script tag integration
Add a single script tag before </body>. Replace the API key with yours from the dashboard.
<script src="https://userdispatch.com/widget.js" data-api-key="pk_your-api-key" defer ></script>
The widget renders a floating feedback button. Users can submit feedback, bug reports (with screenshots via drag-and-drop), and questions.
Alternative: link-based integration
If you prefer not to use the floating widget, you can embed a simple link or button on your site that opens a hosted feedback page:
<a href="https://userdispatch.com/submit?key=pk_your-api-key"> Give Feedback </a>
This is useful for email signatures, documentation footers, or anywhere you want a lightweight feedback entry point without loading the widget script.
Framework guides
Use the Script component in your root layout:
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://userdispatch.com/widget.js"
data-api-key="pk_your-api-key"
strategy="afterInteractive"
/>
</body>
</html>
);
}Configuration options
Configure the widget via data attributes on the script tag:
| Attribute | Required | Default | Description |
|---|---|---|---|
| data-api-key | Yes | — | Your app's API key (starts with pk_) |
| data-position | No | "br" | Trigger button position: "br" (bottom-right), "bl", "tr", "tl" |
| data-trigger-label | No | "Feedback" | Text on the trigger button |
| data-collect-email | No | "true" | Show email field. Set to "false" to hide. |
| data-collect-name | No | "false" | Show name field. Set to "true" to enable. |
| data-enable-logs | No | "false" | Enable built-in console log collector. Set to "true" to enable. Requires app-level log upload setting. |
| data-api-url | No | (auto-detected) | Override the API base URL. Detected automatically from the script src. |
JavaScript API
For programmatic control, use the global UserDispatch object:
// Initialize with custom config
const widget = UserDispatch.init({
apiKey: "pk_your-api-key",
position: "br",
triggerLabel: "Send Feedback",
darkMode: true,
types: ["general", "support", "bug"],
collectEmail: true,
collectName: false,
metadata: { plan: "pro", version: "2.1.0" },
userContext: { id: "user_123", name: "Jane" },
onSubmit: (result) => console.log("Submitted:", result),
onError: (error) => console.error("Error:", error),
});
// Later: remove the widget
widget.destroy();Programmatic submission (no UI)
await UserDispatch.submit({
apiKey: "pk_your-api-key",
type: "bug",
email: "user@example.com",
subject: "Page crash on checkout",
message: "The page freezes when clicking Pay",
metadata: { page: "/checkout", cartId: "abc123" },
});SDK (@userdispatch/sdk)
The TypeScript SDK provides a clean API for server-side or programmatic use:
npm install @userdispatch/sdk
import { UserDispatch } from "@userdispatch/sdk";
const ud = new UserDispatch({ apiKey: "pk_your-api-key" });
// Submit feedback
await ud.submit({
type: "feedback",
message: "Love the new dashboard!",
rating: 5,
email: "user@example.com",
});
// Submit an automated log
await ud.submitLog({
message: "Unhandled promise rejection in /api/checkout",
metadata: {
stack: "Error: timeout at fetch.js:42",
severity: "error",
},
});Submission types
| Widget type | DB type | Description |
|---|---|---|
| general | feedback | General feedback with optional star rating |
| support | question | Support questions |
| bug | bug_report | Bug reports with subject line and file attachments |
| — | automated_log | Automated logs via SDK (no widget equivalent) |
File uploads
Users can attach files by dragging and dropping anywhere on the widget modal. Supported formats include images (PNG, JPG, GIF, WebP), documents (PDF), and text files. Files are attached to the submission and accessible from the dashboard.
Browser metadata
Every submission automatically captures:
- User agent string
- Viewport dimensions
- Page URL
- Operating system
- Screen resolution
- Custom metadata (via
data-*attributes or JS API)