When This Rule Applies
Apply when implementing error tracking, performance monitoring, or release management with Sentry.
Source Maps Configuration
Next.js with withSentryConfig
javascript
// next.config.js
const { withSentryConfig } = require("@sentry/nextjs");
module.exports = withSentryConfig(
{ reactStrictMode: true },
{
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
sourcemaps: {
deleteSourcemapsAfterUpload: true, // CRITICAL: Security
},
tunnelRoute: "/sentry-tunnel", // Bypass ad blockers
}
);
Vite/React
javascript
// vite.config.ts
import * as Sentry from '@sentry/vite-plugin';
export default defineConfig({
build: { sourcemap: true },
plugins: [
react(),
Sentry.sentryVitePlugin({
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN,
}),
],
});
Performance Monitoring
React Initialization with Tracing
javascript
import * as Sentry from "@sentry/react";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
integrations: [new Sentry.BrowserTracing()],
// Production: 10% sampling. Dev: 100%
tracesSampleRate: process.env.NODE_ENV === "production" ? 0.1 : 1.0,
// Capture 100% of sessions with errors
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
environment: process.env.NODE_ENV,
release: process.env.NEXT_PUBLIC_RELEASE,
});
Dynamic Sampling (Capture More of What Matters)
javascript
Sentry.init({
tracesSampler(context) {
// Always inherit distributed tracing decisions
if (context.parentSampled !== undefined) return context.parentSampled;
// Sample database ops at 80%
if (context.transactionContext.op === "db") return 0.8;
// Sample background jobs less
if (context.transactionContext.op === "queue") return 0.1;
return 0.2; // Default
},
});
Issue Grouping & Fingerprinting
Server-Side Fingerprint Rules
Configure in Sentry Dashboard → Project Settings → Issue Grouping:
code
# Group all database connection errors together
error.type:DatabaseConnectionError -> database-unavailable
# Group API errors by status + endpoint
error.type:ApiError error.value:"*status:4*" -> api-4xx, {{ tags.endpoint }}
# Group chunk loading errors by bundle version
error.type:ChunkLoadError -> chunk-load-error, {{ tags.bundle_version }}
SDK-Level Fingerprinting
javascript
Sentry.init({
beforeSend(event) {
// Custom grouping for API errors
if (event.exception?.[0]?.type === "ApiError") {
const status = event.exception[0].value?.match(/status:(\d+)/)?.[1];
event.fingerprint = ["api-error", status || "unknown"];
}
return event;
},
});
Release Tracking
GitHub Actions Integration
yaml
- name: Sentry Release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: your-org
SENTRY_PROJECT: your-project
with:
environment: production
version: ${{ github.sha }}
sourcemaps: ./dist
Common Gotchas
Source Maps Not Working
- •URL prefix mismatch: Ensure
url_prefixmatches deployed paths exactly - •Maps not uploaded: Check CI logs for upload confirmation
- •Maps exposed publicly: Always set
deleteSourcemapsAfterUpload: true
Ad Blockers Blocking Sentry
Use tunneling to route events through your server:
javascript
// In Sentry config tunnelRoute: "/sentry-tunnel"
javascript
// API route (Next.js example)
export async function POST(req) {
const envelope = await req.text();
await fetch("https://sentry.io/api/envelope/", {
method: "POST",
body: envelope,
});
return new Response("OK");
}
Session Replay Quota
javascript
// Sample 10% of sessions, but 100% of error sessions replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0,
React Error Boundaries
javascript
import * as Sentry from "@sentry/react";
root.render(
<Sentry.ErrorBoundary fallback={<ErrorFallback />}>
<App />
</Sentry.ErrorBoundary>
);
Filtering Noise
javascript
Sentry.init({
ignoreErrors: [
/ResizeObserver loop/,
/chrome-extension:/,
/moz-extension:/,
],
beforeSend(event) {
// Filter third-party errors
if (event.request?.url?.includes("/third-party")) return null;
return event;
},
});
Quick Reference
| Task | Pattern |
|---|---|
| Enable source maps | sourcemap: true + upload plugin |
| Performance sampling | tracesSampleRate: 0.1 (production) |
| Custom grouping | event.fingerprint = [...] |
| Release tracking | GitHub Action + release in init |
| Bypass ad blockers | tunnelRoute option |
| Reduce replay quota | replaysSessionSampleRate: 0.1 |