ai-app-feedback
v0.1.0
Published
A Next.js-ready feedback widget that captures user reports, navigation context, screenshots, and AI-agent triage prompts.
Readme
ai-app-feedback
A Next.js-ready feedback widget that helps users send useful reports and gives developers enough context to reproduce issues. It captures recent navigation, selected interaction events, browser context, optional screenshots, and a prompt formatted for coding AI triage.
Install
bun add ai-app-feedbackNext.js App Router
Import the stylesheet once, then wrap the app in NextFeedbackProvider.
// app/layout.tsx
import "ai-app-feedback/style.css";
import { NextFeedbackProvider } from "ai-app-feedback/next";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<NextFeedbackProvider
appId="acme-web"
endpoint="/api/feedback"
metadata={{ environment: process.env.NEXT_PUBLIC_VERCEL_ENV ?? "local" }}
>
{children}
</NextFeedbackProvider>
</body>
</html>
);
}Create an endpoint that stores the report, forwards it to an issue tracker, or hands developerPrompt to your coding AI agent.
// app/api/feedback/route.ts
import type { FeedbackReport } from "ai-app-feedback";
export async function POST(request: Request) {
const report = (await request.json()) as FeedbackReport;
console.log(report.developerPrompt);
return Response.json({ ok: true });
}Screenshot capture
By default, screenshots use the browser getDisplayMedia permission flow when a user submits with screenshots enabled. Browsers do not allow silent page screenshots from arbitrary client code.
For DOM-rendered screenshots, install html2canvas in the host app and pass a custom capture function:
import { createHtml2CanvasCapture } from "ai-app-feedback";
<NextFeedbackProvider
endpoint="/api/feedback"
captureScreenshot={createHtml2CanvasCapture(() => import("html2canvas"))}
>
{children}
</NextFeedbackProvider>;Core API
Use the core session outside Next.js or with a custom UI.
import { createFeedbackSession } from "ai-app-feedback/core";
const session = createFeedbackSession({
appId: "admin",
endpoint: "/api/feedback",
});
session.recordNavigation({ url: window.location.href, title: document.title });
await session.submit({
message: "The export button does nothing.",
expected: "A CSV file should download.",
severity: "high",
category: "bug",
});Privacy defaults
- Input values are not recorded.
- Click tracking stores a small element summary, not full DOM snapshots.
- Screenshot capture is user-visible and permission-gated unless you provide a custom capture function.
- URLs are captured in full by default; pass
scrubUrlto strip query strings or tokens before they are recorded. - Reports include
developerPrompt, a concise repro bundle intended for issue triage and coding agents.
<NextFeedbackProvider
endpoint="/api/feedback"
scrubUrl={(url) => url.split("?")[0] ?? url}
>developerPrompt contains end-user-controlled text fenced inside <untrusted_user_content> tags. If you hand it to a coding agent, run that agent with restricted permissions and treat the fenced content as data, not instructions.
Development
bun install
bun test
bun run build