All guides

Getting started

Add Glitchgrab to your Next.js app

Install the glitchgrab SDK, add the report button and turn on automatic error capture in a Next.js app

Steps checked September 12, 2026

The glitchgrab package adds a Report Bug button and automatic error capture to a Next.js app (13, 14 or 15). Every report becomes a GitHub issue on your repo, with a screenshot, the page, the browser and what the person clicked before it went wrong.

Before you start

  • A gg_ token for the repo reports should go to (see Create an API token).
  • The Glitchgrab GitHub App installed on that repo, or reports arrive without becoming issues.

1. Install

npm install glitchgrab
# or
bun add glitchgrab

2. Add your token

Put the token in your environment. It is safe in a NEXT_PUBLIC_ variable — it is meant to ship to the browser.

# .env.local
NEXT_PUBLIC_GLITCHGRAB_TOKEN=gg_your_token_here

3. Wrap your app

// app/layout.tsx
import { GlitchgrabProvider } from "glitchgrab";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <GlitchgrabProvider token={process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!}>
          {children}
        </GlitchgrabProvider>
      </body>
    </html>
  );
}

That alone turns on automatic error capture: an unhandled error in production becomes an issue. It is switched off while NODE_ENV is development, so your local errors do not flood the repo.

4. Add the report button

import { ReportButton } from "glitchgrab";

<ReportButton position="bottom-right" label="Report Bug" />

A floating button appears. Pressing it — or ⌘⇧G (Ctrl+Shift+G on Windows) anywhere in your app — opens the report dialog. See What your users see when they report a bug.

Use your own button instead

<ReportButton>
  {({ onClick, capturing }) => (
    <button onClick={onClick} disabled={capturing}>
      {capturing ? "Capturing..." : "Report a Bug"}
    </button>
  )}
</ReportButton>

Pass the logged-in user so every report tells you who sent it. userId and name are required; email and phone are optional.

"use client";
import { GlitchgrabProvider, type GlitchgrabSession } from "glitchgrab";
import { useSession } from "next-auth/react"; // or your auth library

export function Providers({ children }: { children: React.ReactNode }) {
  const { data } = useSession();

  const session: GlitchgrabSession | null = data?.user
    ? {
        userId: data.user.id,   // your database's primary key
        name: data.user.name,
        email: data.user.email,
      }
    : null;

  return (
    <GlitchgrabProvider token={process.env.NEXT_PUBLIC_GLITCHGRAB_TOKEN!} session={session}>
      {children}
    </GlitchgrabProvider>
  );
}

The userId is stored with every report, so you can look the person up in your own database.

6. Check it works

  1. Deploy, or run a production build locally (next build && next start — auto-capture is off in dev, but the button works everywhere).
  2. Press the Report Bug button, describe anything, press Send Report.
  3. You should see a new issue on the GitHub repo within a few seconds, and the report on the Reports page of your dashboard.

Report from your own code

import { useGlitchgrab } from "glitchgrab";

const { reportBug, openReportDialog, addBreadcrumb } = useGlitchgrab();

await reportBug("Checkout button does nothing on mobile"); // no dialog
openReportDialog({ description: "Error on /settings" });   // opens the dialog, pre-filled
addBreadcrumb("User clicked checkout", { cartSize: "3" }); // extra context for the next report

openReportDialog() needs a <ReportButton> mounted somewhere on the page.

Catch errors from error boundaries

Next.js error.tsx catches errors before they reach the global handler, so report them from there:

// app/error.tsx
"use client";
import { useEffect } from "react";
import { useGlitchgrab } from "glitchgrab";

export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
  const { captureError } = useGlitchgrab();
  useEffect(() => {
    captureError(error, { digest: error.digest, boundary: "next-app-router" });
  }, [error, captureError]);
  return <button onClick={reset}>Try again</button>;
}

In app/global-error.tsx, which renders outside the provider, import captureError directly from "glitchgrab" instead of using the hook. An identical error repeating within 5 minutes files one issue, not many.

Provider options

PropWhat it does
tokenYour gg_ token (required)
sessionThe logged-in user: userId, name, email, phone
breadcrumbsRecord clicks and requests before a report (default on)
ignoreErrorsSkip auto-capture for errors matching a string or RegExp
releaseA version or commit SHA stamped on every report
contextYour own key-values on every report (org, plan, flags)
onReportSentCalled after a report is sent

Good to know

  • The SDK never crashes your app. Every call is wrapped; a failure is silent.
  • Sensitive URL parameters are stripped (tokens, keys) before a page address is sent.
  • Errors in API routes, cron jobs and workers are not seen by the browser SDK — see Capture errors from your server.
  • Want the AI assistant in the dialog? See Turn on the AI report assistant.

Troubleshooting

  • No button appearsReportButton must be inside GlitchgrabProvider.
  • Reports show on the dashboard but no GitHub issue — see A report did not become a GitHub issue.
  • Nothing is captured locally — expected: automatic capture is off in development. Use the button, or captureError, which runs in development too.
  • The same error keeps being ignored — check ignoreErrors, and remember identical errors within 5 minutes are merged.
Still stuck? Press ⌘⇧G on any Glitchgrab page to tell us — or see the SDK docs.