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.
| Pattern | Best for |
|---|---|
| Error reporting modal | Support agents triaging tickets |
| Embedded dashboard widget | Internal admin tools |
| Custom branded UI | Apps with strong design systems |
| Production monitoring embed | Customer-facing apps, no React |
| Support tooling with follow-ups | Agents iterating on a diagnosis |
| Feedback collection | Tracking 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.
