Documentation source
Sentry
Error monitoring, performance tracing, and session replay with Sentry -- setup, configuration, source maps, and alerting.
# Sentry
The Sprinter Platform uses [Sentry](https://sentry.io) (`@sentry/nextjs@10`) for error tracking, performance monitoring, and session replay. Sentry captures unhandled exceptions, tracks request latency, and records user sessions on error for debugging.
## Architecture
Sentry is initialized in three runtime contexts:
| File | Runtime | Purpose |
|------|---------|---------|
| `instrumentation-client.ts` | Browser | Client-side errors, replay, performance |
| `sentry.server.config.ts` | Node.js server | Server-side errors, API route tracing |
| `sentry.edge.config.ts` | Edge runtime | Middleware and edge route errors |
The Next.js config at `next.config.ts` wraps the build with `withSentryConfig()` to handle source map upload and auto-instrumentation:
```typescript
export default withSentryConfig(withMDX(nextConfig), {
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: !process.env.CI,
sourcemaps: {
disable: process.env.CI !== "true" && process.env.SENTRY_UPLOAD_MAPS !== "true",
deleteSourcemapsAfterUpload: true,
},
tunnelRoute: "/monitoring",
autoInstrumentServerFunctions: true,
autoInstrumentMiddleware: true,
autoInstrumentAppDirectory: true,
});
```
## Tunnel route
Browser requests to Sentry are routed through `/monitoring` on the Next.js server. This tunnels Sentry SDK traffic through your own domain, bypassing ad-blockers that block direct requests to `*.ingest.sentry.io`. No separate route file is needed -- the `tunnelRoute` config handles it automatically.
## Global error boundary
`app/global-error.tsx` catches unhandled errors at the top of the React tree and reports them to Sentry:
```typescript
Sentry.captureException(error);
```
This ensures that even catastrophic render failures are captured.
## Sampling rates
| Runtime | Traces (prod) | Traces (dev) | Replay on error (prod) |
|---------|--------------|--------------|------------------------|
| Client | 10% | 100% (disabled by default) | 100% |
| Server | 10% | 100% (disabled by default) | -- |
| Edge | 5% | 100% (disabled by default) | -- |
Session replay is disabled in development to avoid quota burn. Replay records user sessions when an error occurs, capturing DOM snapshots with text masking and media blocking for privacy.
The client SDK is disabled entirely in development unless `SENTRY_ENABLE_DEV=true` is set:
```typescript
enabled: process.env.NODE_ENV !== "development" || process.env.SENTRY_ENABLE_DEV === "true",
```
## Source maps
Source maps are uploaded to Sentry only in CI builds (where `CI=true` is set automatically by Vercel) or when `SENTRY_UPLOAD_MAPS=true` is set locally. After upload, source maps are deleted from the build output to prevent exposure.
Without source maps, Sentry still captures errors but stack traces reference minified code, making debugging harder.
## Release tracking
Sentry associates errors with specific releases. On Vercel, the `@sentry/nextjs` webpack plugin automatically uses `VERCEL_GIT_COMMIT_SHA` as the release identifier.
For self-hosted or custom CI environments:
```bash
export SENTRY_RELEASE=$(git rev-parse --short HEAD)
```
## Manual capture
Add custom error reporting, user context, and breadcrumbs:
```typescript
import * as Sentry from "@sentry/nextjs";
// Capture a custom error
Sentry.captureException(new Error("something went wrong"));
// Set user context for all subsequent events
Sentry.setUser({ id: userId, email: user.email });
Sentry.setTag("tenant_id", tenantId);
// Add navigation breadcrumb
Sentry.addBreadcrumb({ message: "User clicked X", category: "ui" });
```
## Required environment variables
| Variable | Purpose |
|----------|---------|
| `NEXT_PUBLIC_SENTRY_DSN` | Client-side DSN (public, embedded in browser bundle) |
| `SENTRY_DSN` | Server-side DSN (same value as public, but available server-side) |
| `SENTRY_AUTH_TOKEN` | Auth token for source map upload in CI |
| `SENTRY_ORG` | Sentry organization slug |
| `SENTRY_PROJECT` | Sentry project name (e.g., `amble`) |
Set these in Vercel > Project > Settings > Environment Variables, scoped to Production (and optionally Preview).
## One-time setup
1. Create a Sentry project at [sentry.io](https://sentry.io) > New Project > Next.js
2. Copy the DSN from Settings > Projects > (your project) > Client Keys (DSN)
3. Create an auth token at [sentry.io/settings/auth-tokens/](https://sentry.io/settings/auth-tokens/) with scopes: `project:releases`, `org:read`, `project:read`, `project:write`
4. Add all five environment variables to Vercel
5. Deploy -- Sentry starts receiving events on the next release
## Alerts
Configure alerts in the Sentry dashboard under Alerts > Create Alert:
- **All unresolved issues** -- send to Slack or email
- **New issue** -- immediate notification on first occurrence
- **Error rate spike** -- alert when error count exceeds baseline
- **p95 latency** -- alert on `/api/*` route latency spikes
## Troubleshooting
**No events appearing:**
- Verify `NEXT_PUBLIC_SENTRY_DSN` is set and the DSN is correct
- Check that the SDK is not disabled in development (set `SENTRY_ENABLE_DEV=true`)
- Ensure the `/monitoring` tunnel route is accessible
**Minified stack traces:**
- Verify `SENTRY_AUTH_TOKEN` is set in CI
- Check that `CI=true` or `SENTRY_UPLOAD_MAPS=true` during build
- Confirm source maps uploaded successfully in CI logs
**High quota usage:**
- Reduce `tracesSampleRate` in the config files
- Disable replay in non-production environments (already default)
- Add `ignoreErrors` patterns for noisy, non-actionable errors