SigSentrySigSentry

Integration patterns

Six common shapes — error reporting modal, embedded dashboard widget, custom branded UI, vanilla embed, support tooling, and feedback collection

The SDK is small on purpose — three components, two hooks, one embed. The shapes below show how teams actually wire it up.

PatternBest for
Error reporting modalSupport agents triaging tickets
Embedded dashboard widgetInternal admin tools
Custom branded UIApps with strong design systems
Production monitoring embedCustomer-facing apps, no React
Support tooling with follow-upsAgents iterating on a diagnosis
Feedback collectionTracking diagnosis quality over time

Pattern 1: Error reporting modal

A floating button on every internal page. Click → modal → describe the error → get a diagnosis. Zero boilerplate beyond the provider.

'use client';

import { SigSentryProvider, SigSentryTrigger } from '@sigsentry/react';

export function SupportShell({ children }: { children: React.ReactNode }): JSX.Element {
  return (
    <SigSentryProvider apiKey={process.env.NEXT_PUBLIC_SIGSENTRY_KEY!} theme="auto">
      {children}
      <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 50 }}>
        <SigSentryTrigger mode="modal" label="Diagnose Error" defaultTimeRange="30m" />
      </div>
    </SigSentryProvider>
  );
}

Pattern 2: Embedded dashboard widget

Drop the inline widget into an existing internal admin tool — for example, a per-customer detail page. The time range and onComplete callback let you persist results into your own DB.

'use client';

import { SigSentryProvider, AnalysisWidget } from '@sigsentry/react';
import type { AnalysisResult } from '@sigsentry/core';

export function CustomerDiagnostics({ customerId }: { customerId: string }): JSX.Element {
  async function persist(result: AnalysisResult): Promise<void> {
    await fetch(`/api/customers/${customerId}/diagnoses`, {
      method: 'POST',
      body: JSON.stringify({ analysisId: result.id, severity: result.severity }),
    });
  }

  return (
    <SigSentryProvider apiKey={process.env.NEXT_PUBLIC_SIGSENTRY_KEY!}>
      <AnalysisWidget
        defaultTimeRange="4h"
        onAnalysisComplete={(r) => void persist(r)}
      />
    </SigSentryProvider>
  );
}

Pattern 3: Custom branded UI

When the bundled widget doesn't match your design system, build the UI yourself with useSigSentry. You get the same streaming, status, and follow-up plumbing — just your components on top.

'use client';

import { useSigSentry, useSigSentryContext, AnalysisResultDisplay } from '@sigsentry/react';

export function BrandedFlow(): JSX.Element {
  const { client } = useSigSentryContext();
  const { submitAnalysis, status, result, error, isLoading } = useSigSentry({ client });

  async function run(formData: FormData): Promise<void> {
    const description = formData.get('description') as string;
    await submitAnalysis({
      description,
      timeStart: new Date(Date.now() - 60 * 60 * 1000),
      timeEnd: new Date(),
    });
  }

  return (
    <div className="my-design-system">
      <form action={run}>
        <textarea name="description" required />
        <button type="submit" disabled={isLoading}>
          {isLoading ? `Working… (${status})` : 'Diagnose'}
        </button>
      </form>
      {error && <p role="alert">{error.message}</p>}
      {result && <AnalysisResultDisplay result={result} />}
    </div>
  );
}

Pattern 4: Production monitoring embed

Ship analysis to a customer-facing app written in something other than React — Vue, Rails, Django, plain HTML. One script tag, done.

<!doctype html>
<html>
  <body>
    <header>
      <div id="sg-trigger"></div>
    </header>

    <script src="https://embed.sigsentry.com/v1/embed.js"></script>
    <script>
      SigSentry.init({
        target: '#sg-trigger',
        apiKey: 'ss_pub_...',
        mode: 'modal',
        triggerLabel: 'Report a problem',
        theme: 'auto',
      });
    </script>
  </body>
</html>

See Vanilla JS embed for the full option list.

Pattern 5: Support tooling with follow-ups

Combine <AnalysisResultDisplay /> with the askFollowUp() hook when agents need to iterate on a diagnosis without leaving the ticket view.

'use client';

import { useState } from 'react';
import {
  AnalysisResultDisplay,
  useSigSentry,
  useSigSentryContext,
} from '@sigsentry/react';

export function TicketDiagnostics(): JSX.Element {
  const { client } = useSigSentryContext();
  const { submitAnalysis, askFollowUp, result, isLoading } = useSigSentry({ client });
  const [question, setQuestion] = useState('');
  const [answer, setAnswer] = useState<string | null>(null);

  async function ask(): Promise<void> {
    const response = await askFollowUp(question);
    if (response?.success && response.data) {
      setAnswer(response.data.answer);
      setQuestion('');
    }
  }

  return (
    <div>
      <button
        onClick={() =>
          submitAnalysis({
            description: 'Customer cannot complete checkout',
            timeStart: new Date(Date.now() - 60 * 60 * 1000),
            timeEnd: new Date(),
          })
        }
        disabled={isLoading}
      >
        Diagnose
      </button>

      {result && (
        <>
          <AnalysisResultDisplay result={result} />
          <input
            value={question}
            onChange={(e) => setQuestion(e.target.value)}
            placeholder="Was this caused by the 14:00 deploy?"
          />
          <button onClick={ask}>Ask</button>
          {answer && <p>{answer}</p>}
        </>
      )}
    </div>
  );
}

Pattern 6: Feedback collection

Track diagnosis quality over time by sending accuracy ratings back through submitFeedback(). Pair it with a custom rating UI that matches your app.

'use client';

import { useSigSentry, useSigSentryContext, AnalysisResultDisplay } from '@sigsentry/react';

export function ResultWithRating(): JSX.Element {
  const { client } = useSigSentryContext();
  const { submitFeedback, result } = useSigSentry({ client });

  async function rate(accuracy: 'correct' | 'partially_correct' | 'incorrect'): Promise<void> {
    await submitFeedback({ accuracy });
  }

  if (!result) return <></>;

  return (
    <div>
      <AnalysisResultDisplay result={result} />
      <div role="group" aria-label="Diagnosis accuracy">
        <button onClick={() => rate('correct')}>Correct</button>
        <button onClick={() => rate('partially_correct')}>Partially correct</button>
        <button onClick={() => rate('incorrect')}>Incorrect</button>
      </div>
    </div>
  );
}

Feedback flows into the dashboard's analysis history so you can spot trends — for example, repeat misdiagnoses on a particular service. See Analyses for what surfaces in the dashboard.